초안 ECMA-262 / 2025년 7월 24일

ECMAScript® 2026 언어 명세서

이 명세에 대해

https://tc39.es/ecma262/ 문서는 가장 정확하고 최신의 ECMAScript 명세입니다. 이 문서에는 최근 연간 스냅샷의 내용과 스냅샷 이후에 완료된 모든 완료된 제안 (제안 프로세스에서 Stage 4에 도달하여 여러 구현에서 적용되었고 다음 실질적인 개정에 포함될 예정인 것)이 포함되어 있습니다.

이 문서는 단일 페이지여러 페이지로 제공됩니다.

이 명세에 기여하기

이 명세는 ECMAScript 커뮤니티의 도움으로 GitHub에서 개발되고 있습니다. 이 명세의 개발에 기여할 수 있는 방법은 여러 가지가 있습니다:

이 문서가 어떻게 만들어지는지에 대한 자세한 내용은 콜로폰을 참고하세요.

소개

이 Ecma 표준은 ECMAScript 2026 언어를 정의합니다. 이것은 ECMAScript 언어 명세의 열일곱 번째 에디션입니다. 1997년 첫 번째 에디션이 출판된 이후, ECMAScript는 세계에서 가장 널리 사용되는 범용 프로그래밍 언어 중 하나로 성장했습니다. 주로 웹 브라우저에 내장된 언어로 잘 알려져 있지만, 서버 및 임베디드 애플리케이션에서도 널리 채택되었습니다.

ECMAScript는 여러 원천 기술을 기반으로 하며, 그 중 가장 잘 알려진 것은 JavaScript(넷스케이프)와 JScript(마이크로소프트)입니다. 이 언어는 넷스케이프의 Brendan Eich가 발명했으며, 처음으로 그 회사의 Navigator 2.0 브라우저에 등장했습니다. 이후 넷스케이프의 모든 브라우저와 마이크로소프트의 Internet Explorer 3.0부터 모든 브라우저에 포함되었습니다.

ECMAScript 언어 명세의 개발은 1996년 11월에 시작되었습니다. 이 Ecma 표준의 첫 번째 에디션은 1997년 6월 Ecma 총회에서 채택되었습니다.

그 Ecma 표준은 ISO/IEC JTC 1에 신속 채택 절차 하에 제출되었으며, 1998년 4월 국제 표준 ISO/IEC 16262로 승인되었습니다. 1998년 6월 Ecma 총회에서 ISO/IEC 16262와 완전히 일치시키기 위해 ECMA-262 두 번째 에디션이 승인되었습니다. 첫 번째와 두 번째 에디션의 차이점은 편집상의 변경입니다.

표준의 세 번째 에디션에서는 강력한 정규식, 향상된 문자열 처리, 새로운 제어문, try/catch 예외 처리, 오류 정의 강화, 숫자 출력 포맷 및 향후 언어 성장에 대비한 사소한 변경이 도입되었습니다. ECMAScript 표준의 세 번째 에디션은 1999년 12월 Ecma 총회에서 채택되었으며, 2002년 6월 ISO/IEC 16262:2002로 출판되었습니다.

세 번째 에디션 출판 이후, ECMAScript는 월드와이드웹과 함께 엄청난 채택을 이루었으며, 사실상 모든 웹 브라우저에서 지원되는 프로그래밍 언어가 되었습니다. ECMAScript의 네 번째 에디션을 개발하기 위한 중요한 작업이 이루어졌으나, 그 작업은 완성되지 않았고 네 번째 에디션으로 출판되지 않았습니다. 다만 일부 내용은 여섯 번째 에디션 개발에 통합되었습니다.

ECMAScript의 다섯 번째 에디션(ECMA-262 5번째 에디션으로 출판됨)은 브라우저 구현에서 일반적으로 사용되는 언어 명세의 사실상 해석을 공식화하였고, 세 번째 에디션 출판 이후 등장한 새로운 기능 지원을 추가했습니다. 이러한 기능에는 접근자 속성, 객체의 반영적 생성 및 검사, 속성 특성의 프로그램 제어, 추가 배열 조작 함수, JSON 객체 인코딩 포맷 지원, 그리고 향상된 오류 검사와 프로그램 보안을 제공하는 엄격 모드가 포함됩니다. 다섯 번째 에디션은 2009년 12월 Ecma 총회에서 채택되었습니다.

다섯 번째 에디션은 신속 채택 절차에 따라 ISO/IEC JTC 1에 제출되어 국제 표준 ISO/IEC 16262:2011로 승인되었습니다. ECMAScript 표준의 5.1 에디션은 사소한 수정이 반영되었으며 ISO/IEC 16262:2011과 동일한 텍스트입니다. 5.1 에디션은 2011년 6월 Ecma 총회에서 채택되었습니다.

여섯 번째 에디션의 집중 개발은 2009년에 시작되었으며, 다섯 번째 에디션이 출판 준비 중이었습니다. 하지만 그 이전에도 1999년 세 번째 에디션 출판 이후 상당한 실험과 언어 개선 디자인 작업이 이루어졌습니다. 실제로 여섯 번째 에디션의 완성은 15년간의 노력의 결실입니다. 이 에디션의 목표는 대규모 애플리케이션, 라이브러리 제작, 그리고 ECMAScript를 다른 언어의 컴파일 타겟으로 사용하는 데 더 나은 지원을 제공하는 것이었습니다. 주요 개선사항에는 모듈, 클래스 선언, 렉시컬 블록 스코프, 이터레이터와 제너레이터, 비동기 프로그래밍을 위한 프라미스, 구조 분해 패턴, 적절한 꼬리 호출이 포함되었습니다. ECMAScript 내장 라이브러리는 맵, 셋, 2진 숫자 값 배열 등의 추가 데이터 추상화 지원과 문자열 및 정규식에서 유니코드 보충 문자 추가 지원을 포함하여 더욱 확장되었습니다. 내장 객체는 서브클래싱을 통해 확장 가능해졌습니다. 여섯 번째 에디션은 정기적이고 점진적인 언어 및 라이브러리 개선의 토대를 제공합니다. 여섯 번째 에디션은 2015년 6월 총회에서 채택되었습니다.

ECMAScript 2016은 Ecma TC39의 새로운 연간 릴리즈 주기와 공개 개발 프로세스 하에서 릴리즈된 첫 번째 ECMAScript 에디션입니다. 텍스트 소스 문서는 ECMAScript 2015 소스에서 제작되어 GitHub에서 추가 개발의 기반이 되었습니다. 표준 개발 기간 동안 수백 개의 풀 리퀘스트와 이슈가 제출되어 수천 건의 버그 수정, 편집 개선 및 기타 향상 작업이 이루어졌습니다. 또한 Ecmarkup, Ecmarkdown, Grammarkdown 등 여러 소프트웨어 도구가 개발되었습니다. ES2016에는 새로운 거듭제곱 연산자와 Array.prototypeincludes 메서드가 추가되었습니다.

ECMAScript 2017은 Async 함수, 공유 메모리, Atomics, 그리고 더 작은 언어 및 라이브러리 개선, 버그 수정, 편집 업데이트를 도입했습니다. Async 함수는 프라미스를 반환하는 함수에 대한 문법을 제공하여 비동기 프로그래밍 경험을 향상시킵니다. 공유 메모리와 Atomics는 병렬 CPU에서도 명확한 실행 순서를 보장하는 원자적 연산을 사용하여 다중 에이전트 프로그램이 통신할 수 있는 새로운 메모리 모델을 도입했습니다. 또한 객체에 대한 새로운 정적 메서드인 Object.values, Object.entries, Object.getOwnPropertyDescriptors도 포함되었습니다.

ECMAScript 2018은 비동기 이터레이터 프로토콜과 async 제너레이터를 통해 비동기 반복 지원을 도입했습니다. 또한 네 가지 새로운 정규식 기능(dotAll 플래그, 명명된 캡처 그룹, 유니코드 속성 이스케이프, 그리고 look-behind 어설션)과 객체의 rest 및 spread 속성을 추가했습니다.

ECMAScript 2019는 Array.prototypeflatflatMap 함수를 통한 배열 평탄화, Object.entries의 반환값을 새 객체로 바로 변환하는 Object.fromEntries, 더 나은 이름의 String.prototype.trimStarttrimEnd 내장 함수(기존 비표준 trimLeft, trimRight 대체용) 등 몇 가지 새로운 내장 함수를 도입했습니다. 또한 문법 및 의미론에 대한 소규모 업데이트(선택적 catch 바인딩 파라미터, JSON과 일치시키기 위해 문자열 리터럴에서 U+2028 및 U+2029 허용 등)가 포함되었습니다. 기타 업데이트에는 Array.prototype.sort의 안정적 정렬 요구, JSON.stringify의 입력에 상관없이 올바른 UTF-8 반환 요구, Function.prototype.toString의 명확화(원본 소스 텍스트 또는 표준 플레이스홀더 반환 요구)가 있습니다.

ECMAScript 2020, 11번째 에디션은 문자열의 matchAll 메서드(글로벌 정규식으로 생성된 모든 매치 객체에 대한 이터레이터 생성), import() 문법(동적 지정자로 모듈을 비동기적으로 import), BigInt(임의 정밀도의 정수를 다루는 새로운 숫자 원시 타입), Promise.allSettled(짧은 회로 없음), globalThis(글로벌 this 값 접근의 범용 방법), 모듈 내 export * as ns from 'module' 문법, for-in 열거 순서의 표준화 강화, 모듈 내에서 컨텍스트 정보를 담을 수 있는 import.meta 객체, nullish 값(undefined 또는 null)을 다루기 위한 새로운 문법(nullish 병합 연산자, 옵셔널 체이닝 연산자) 등을 도입했습니다.

ECMAScript 2021, 12번째 에디션은 문자열의 replaceAll 메서드, Promise.any(입력값이 fulfill될 때 짧은 회로), AggregateError(여러 오류를 한 번에 표현하는 새로운 오류 타입), 논리 할당 연산자(??=, &&=, ||=), WeakRef(가비지 컬렉션에서 객체를 보존하지 않고 참조), FinalizationRegistry(가비지 컬렉션 시 정리 작업 등록 및 해제 관리), 숫자 리터럴 구분자(1_000), Array.prototype.sort의 구현 정의 정렬 순서 정렬 순서의 경우 감소 등 다양한 기능을 도입했습니다.

ECMAScript 2022, 13번째 에디션은 모듈의 최상위에서 await 사용을 허용하는 기능, 클래스 내의 새로운 요소(퍼블릭 및 프라이빗 인스턴스 필드, 퍼블릭 및 프라이빗 정적 필드, 프라이빗 인스턴스 메서드 및 접근자, 프라이빗 정적 메서드 및 접근자), 클래스 내 정적 블록(클래스별 평가 초기화 수행), #x in obj 문법(객체에 프라이빗 필드 존재 여부 테스트), /d 플래그(정규식 매치 인덱스 제공), Error 객체의 cause 속성(에러의 원인 연쇄 기록), 문자열, 배열, TypedArrayat 메서드(상대 인덱싱 지원), Object.hasOwn(Object.prototype.hasOwnProperty의 편리한 대안) 등을 도입했습니다.

ECMAScript 2023, 14번째 에디션은 Array.prototypeTypedArray.prototypetoSorted, toReversed, with, findLast, findLastIndex 메서드, Array.prototypetoSpliced 메서드, 파일 시작 부분에 #! 주석 지원(실행 가능한 ECMAScript 파일 지원 향상), 대부분의 심볼을 weak 컬렉션의 키로 사용 가능 등 기능을 도입했습니다.

ECMAScript 2024, 15번째 에디션은 ArrayBuffer 및 SharedArrayBuffer의 리사이즈 및 전송 기능, 문자열 집합 작업을 위한 고급 기능의 새로운 RegExp /v 플래그, Promise 생성 편의 메서드 Promise.withResolvers, 데이터 집계용 Object.groupByMap.groupBy 메서드, 공유 메모리 변경을 비동기적으로 대기하는 Atomics.waitAsync 메서드, 문자열의 올바른 유니코드만 포함되는지 검사 및 보장하는 String.prototype.isWellFormedString.prototype.toWellFormed 메서드 등을 도입했습니다.

ECMAScript 2025, 16번째 에디션은 이터레이터 작업을 위한 새로운 Iterator 글로벌과 관련 정적 및 프로토타입 메서드, Set.prototype의 일반적 셋 연산 메서드, JSON 모듈 import 및 import된 모듈의 속성 선언 문법, 정규식 내 안전한 문자열 사용을 위한 RegExp.escape 메서드, 정규식 내에서 인라인으로 modifier 플래그 활성/비활성화 문법, 함수의 반환값이 프라미스일 수도 아닐 수도 있을 때 항상 프라미스로 반환하는 Promise.try 메서드, 새로운 Float16Array TypedArray 종류와 관련 DataView.prototype.getFloat16, DataView.prototype.setFloat16, Math.f16round 메서드를 도입했습니다.

Ecma TC39 내에서 많은 조직을 대표하는 수십 명의 개인이 이 에디션과 이전 에디션의 개발에 매우 중요한 기여를 했습니다. 또한 TC39의 ECMAScript 작업을 지원하는 활발한 커뮤니티가 생겨났습니다. 이 커뮤니티는 수많은 초안 검토, 수천 건의 버그 리포트 제출, 구현 실험, 테스트 스위트 기여, ECMAScript에 대한 전 세계 개발자 교육 등 다양한 활동을 했습니다. 모든 기여자와 조직을 식별하고 인정하는 것은 불가능합니다.

Allen Wirfs-Brock
ECMA-262, 프로젝트 에디터, 6번째 에디션

Brian Terlson
ECMA-262, 프로젝트 에디터, 7번째 ~ 10번째 에디션

Jordan Harband
ECMA-262, 프로젝트 에디터, 10번째 ~ 12번째 에디션

Shu-yu Guo
ECMA-262, 프로젝트 에디터, 12번째 ~ 16번째 에디션

Michael Ficarra
ECMA-262, 프로젝트 에디터, 12번째 ~ 16번째 에디션

Kevin Gibbons
ECMA-262, 프로젝트 에디터, 12번째 ~ 16번째 에디션

1 범위

이 표준은 ECMAScript 2026 범용 프로그래밍 언어를 정의합니다.

2 준수

ECMAScript의 준수 구현체는 이 명세서에 기술된 모든 타입, 값, 객체, 프로퍼티, 함수, 프로그램 구문 및 의미론을 제공하고 지원해야 합니다.

ECMAScript의 준수 구현체는 소스 텍스트 입력을 최신 버전의 유니코드 표준 및 ISO/IEC 10646에 따라 해석해야 합니다.

다양한 인간 언어와 국가에서 사용되는 언어적, 문화적 관습에 적응이 필요한 프로그램을 지원하는 API를 제공하는 ECMAScript의 준수 구현체는 이 명세서와 호환되는 ECMA-402의 최신판에서 정의된 인터페이스를 구현해야 합니다.

ECMAScript의 준수 구현체는 이 명세서에 기술된 것 이외의 추가 타입, 값, 객체, 프로퍼티, 함수 등을 제공할 수 있습니다. 특히, 준수 구현체는 명세서에 기술되지 않은 프로퍼티와 그 값, 그리고 명세서에 기술된 객체에 대해 추가 프로퍼티를 제공할 수 있습니다.

ECMAScript의 준수 구현체는 이 명세서에 기술되지 않은 프로그램 및 정규식 구문을 지원할 수 있습니다. 특히, 준수 구현체는 이 명세서의 예약어로 지정된 “미래 12.7.2”를 사용하는 프로그램 구문을 지원할 수 있습니다.

ECMAScript의 준수 구현체는 17.1절에서 금지 확장으로 명시된 어떤 확장도 구현해서는 안 됩니다.

ECMAScript의 준수 구현체는 구현 정의, 구현 근사, 또는 호스트 정의가 아닌 어떤 기능도 재정의해서는 안 됩니다.

ECMAScript의 준수 구현체는 규범적 선택 사항 절을 구현할지 말지 선택할 수 있습니다. 어떤 규범적 선택 사항 동작을 구현하는 경우, 해당 규범적 선택 사항 절의 모든 동작을 구현해야 합니다. 규범적 선택 사항 절은 아래와 같이 색상 박스에 “Normative Optional”이라는 단어로 표시됩니다.

2.1 규범적 선택 사항 절 제목 예시

절 내용 예시.

ECMAScript의 준수 구현체는 규범적 선택 사항으로도 표시되지 않는 레거시 절을 반드시 구현해야 합니다. 레거시 절 내에 명시된 모든 언어 기능과 동작은 하나 이상의 바람직하지 않은 특성을 가지고 있습니다. 그러나 기존 애플리케이션에서 계속 사용되고 있기 때문에 이 명세서에서 제거할 수 없습니다. 이러한 기능은 ECMAScript 언어의 핵심에 해당하지 않습니다. 새로운 ECMAScript 코드를 작성할 때 프로그래머는 이러한 기능과 동작을 사용하거나 존재를 가정해서는 안 됩니다.

2.2 레거시 절 제목 예시

절 내용 예시.

2.3 레거시 규범적 선택 사항 절 제목 예시

절 내용 예시.

3 규범적 참고문헌

다음에 참조된 문서는 이 문서의 적용에 필수적입니다. 날짜가 명시된 참고문헌의 경우, 인용된 판만 적용됩니다. 날짜가 명시되지 않은 참고문헌의 경우, 해당 문서의 최신판(모든 개정 포함)이 적용됩니다.

IEEE 754-2019, IEEE 부동소수점 산술 표준.

유니코드 표준.
https://unicode.org/versions/latest

ISO/IEC 10646, 정보 기술 — 범용 다중-옥텟 인코딩 문자 집합(UCS) 및 Amendment 1:2005, Amendment 2:2006, Amendment 3:2008, Amendment 4:2008, 그리고 추가 개정 및 정오표, 또는 후속판.

ECMA-402, ECMAScript 국제화 API 명세, 특히 이 명세의 해당 연도판.
https://www.ecma-international.org/publications-and-standards/standards/ecma-402/

ECMA-404, JSON 데이터 교환 포맷.
https://www.ecma-international.org/publications-and-standards/standards/ecma-404/

4 개요

이 절은 ECMAScript 언어에 대한 비규범적 개요를 포함합니다.

ECMAScript는 호스트 환경 내에서 계산을 수행하고 계산 객체를 조작하기 위한 객체 지향 프로그래밍 언어입니다. 여기서 정의된 ECMAScript는 계산적으로 자급자족하는 것을 목표로 하지 않습니다. 실제로, 이 명세에는 외부 데이터 입력이나 계산 결과 출력을 위한 규정이 없습니다. 대신, ECMAScript 프로그램의 계산 환경은 이 명세에 설명된 객체 및 기타 기능뿐만 아니라, 환경별 객체도 제공할 것으로 예상되며, 이러한 객체의 설명과 동작은 이 명세의 범위를 벗어나지만 특정 속성에 접근하거나 ECMAScript 프로그램에서 호출할 수 있는 함수가 있을 수 있음을 나타냅니다.

ECMAScript는 원래 스크립트 언어로 설계되었으나, 현재는 범용 프로그래밍 언어로 널리 사용되고 있습니다. 스크립트 언어는 기존 시스템의 기능을 조작, 사용자화, 자동화하는 데 사용되는 프로그래밍 언어입니다. 이러한 시스템에서는 이미 유용한 기능이 사용자 인터페이스를 통해 제공되고, 스크립트 언어는 해당 기능을 프로그램 제어로 노출하는 수단입니다. 이렇게 기존 시스템이 호스트 환경의 객체와 기능을 제공하여 스크립트 언어의 역량을 완성합니다. 스크립트 언어는 전문가와 비전문가 모두 사용할 수 있도록 설계되었습니다.

ECMAScript는 원래 웹 스크립트 언어로 설계되어 브라우저에서 웹 페이지에 생동감을 부여하거나 웹 기반 클라이언트-서버 구조에서 서버 계산을 수행하는 메커니즘을 제공했습니다. ECMAScript는 이제 다양한 호스트 환경에서 핵심 스크립트 기능을 제공합니다. 따라서 핵심 언어는 특정 호스트 환경과 별도로 이 문서에서 명세됩니다.

ECMAScript의 사용은 단순 스크립트에서 벗어나 현재는 여러 환경과 규모에서 모든 프로그래밍 작업에 사용됩니다. ECMAScript의 사용이 확장됨에 따라 제공하는 기능과 설비도 확장되었습니다. ECMAScript는 이제 완전한 범용 프로그래밍 언어입니다.

4.1 웹 스크립팅

웹 브라우저는 클라이언트 측 계산을 위한 ECMAScript 호스트 환경을 제공합니다. 여기에는 예를 들어, 창, 메뉴, 팝업, 대화 상자, 텍스트 영역, 앵커, 프레임, 히스토리, 쿠키, 입출력을 나타내는 객체 등이 포함됩니다. 또한 호스트 환경은 포커스 변경, 페이지 및 이미지 로딩, 언로드, 오류 및 중단, 선택, 폼 제출, 마우스 동작 등 이벤트에 스크립트 코드를 연결하는 방법을 제공합니다. 스크립트 코드는 HTML 내에 나타나며, 표시되는 페이지는 사용자 인터페이스 요소와 고정 및 계산된 텍스트 및 이미지의 조합입니다. 스크립트 코드는 사용자 상호작용에 반응하며, 메인 프로그램이 필요하지 않습니다.

웹 서버는 요청, 클라이언트, 파일을 나타내는 객체, 데이터 잠금 및 공유 메커니즘 등 서버 측 계산을 위한 별도의 호스트 환경을 제공합니다. 브라우저 측과 서버 측 스크립팅을 함께 사용하면, 사용자 맞춤형 웹 애플리케이션에서 클라이언트와 서버 간에 계산을 분산시킬 수 있습니다.

ECMAScript를 지원하는 각 웹 브라우저와 서버는 자체 호스트 환경을 제공하여 ECMAScript 실행 환경을 완성합니다.

4.2 호스트와 구현체

호스트 환경에 ECMAScript 통합을 돕기 위해, 이 명세는 특정 기능(예: 추상 연산)의 정의를 전체 또는 일부 외부 소스에 위임합니다. 편집상, 이 명세는 다음과 같은 위임 유형을 구분합니다.

구현체는 부록 D에 열거된 기능이나 구현 정의 또는 구현 근사로 표시된 기능을 외부에서 추가 정의하는 소스입니다. 비공식적으로, 구현체는 특정 웹 브라우저와 같은 구체적인 산출물을 의미합니다.

구현 정의 기능은 추가적인 자격 없이 정의를 외부 소스에 위임하는 기능입니다. 이 명세는 특정 동작에 대한 권고를 하지 않으며, 준수 구현체는 이 명세가 제시하는 제약 내에서 어떤 동작이든 자유롭게 선택할 수 있습니다.

구현 근사 기능은 이상적인 동작을 권고하면서 정의를 외부 소스에 위임하는 기능입니다. 준수 구현체는 이 명세가 제시하는 제약 내에서 어떤 동작이든 자유롭게 선택할 수 있지만, 이상적인 동작에 근접하도록 노력해야 합니다. Math.exp와 같은 일부 수학 연산은 구현 근사에 해당합니다.

호스트는 부록 D에 열거된 기능을 추가 정의하지만, 그 외의 구현 정의 또는 구현 근사 기능은 추가 정의하지 않는 외부 소스입니다. 비공식적으로, 호스트는 부록 D를 통해 이 명세와 같은 방식으로 연결되는 모든 구현체 집합(모든 웹 브라우저 집합 등)을 의미합니다. 호스트는 종종 WHATWG HTML(https://html.spec.whatwg.org/)과 같은 외부 명세입니다. 즉, 호스트 정의 기능은 종종 외부 명세에서 추가로 정의됩니다.

호스트 후크는 전체 또는 일부가 외부 소스에 의해 정의되는 추상 연산입니다. 모든 호스트 후크는 부록 D에 나열되어야 합니다. 호스트 후크는 최소한 다음 요구사항을 충족해야 합니다:

호스트 정의 기능은 추가적인 자격 없이 정의를 외부 소스에 위임하며, 부록 D에 나열되어야 합니다. 호스트가 아닌 구현체도 호스트 정의 기능에 대한 정의를 제공할 수 있습니다.

호스트 환경은 모든 호스트 정의 기능에 대한 구체적 정의 선택입니다. 호스트 환경에는 일반적으로 호스트 정의 속성으로 입력을 얻거나 출력을 제공하는 객체 또는 함수가 포함되고, 이는 글로벌 객체에 속합니다.

이 명세는 항상 가장 구체적인 용어를 사용하는 편집 관례를 따릅니다. 예를 들어, 어떤 기능이 호스트 정의라면, 구현 정의로 언급해서는 안 됩니다.

호스트와 구현체 모두 이 명세가 정의한 언어 타입, 명세 타입, 추상 연산, 문법 생성규칙, 내장 객체, 내장 심볼을 통해 이 명세와 인터페이스할 수 있습니다.

4.3 ECMAScript 개요

다음은 ECMAScript에 대한 비공식적 개요입니다. 언어의 모든 부분이 설명된 것은 아니며, 이 개요는 표준의 일부가 아닙니다.

ECMAScript는 객체 기반입니다. 기본 언어 및 호스트 기능이 객체로 제공되며, ECMAScript 프로그램은 서로 통신하는 객체 집합입니다. ECMAScript에서 객체는 0개 이상의 프로퍼티로 이루어진 컬렉션이며, 각 프로퍼티는 해당 프로퍼티의 사용 방식을 결정하는 속성을 가집니다. 예를 들어, 프로퍼티의 Writable 속성이 false로 설정된 경우, ECMAScript 코드가 해당 프로퍼티에 다른 값을 할당하려는 모든 시도는 실패합니다. 프로퍼티는 다른 객체, 프리미티브 값, 또는 함수를 저장하는 컨테이너입니다. 프리미티브 값은 다음 내장 타입 중 하나에 속합니다: Undefined, Null, Boolean, Number, BigInt, String, Symbol; 객체는 내장 타입 Object에 속하며, 함수는 호출 가능한 객체입니다. 객체에 프로퍼티로 연결된 함수를 메서드라고 합니다.

ECMAScript는 ECMAScript 엔티티 정의를 완성하는 내장 객체 집합도 정의합니다. 이러한 내장 객체에는 글로벌 객체, 언어의 런타임 의미론에 기본적인 객체들(Object, Function, Boolean, Symbol, 다양한 Error 객체), 숫자 값을 나타내고 조작하는 객체들(Math, Number, Date), 텍스트 처리 객체(String, RegExp), 값이 인덱스된 컬렉션(Array 및 9종의 Typed Array), 키 기반 컬렉션(Map, Set 객체), 구조화된 데이터 지원(JSON 객체, ArrayBuffer, SharedArrayBuffer, DataView), 제어 추상화를 지원하는 객체(제너레이터 함수, Promise 객체), 그리고 반영 객체(Proxy, Reflect)가 포함됩니다.

ECMAScript는 내장 연산자 집합도 정의합니다. ECMAScript 연산자에는 다양한 단항 연산, 곱셈 연산자, 덧셈 연산자, 비트 시프트 연산자, 관계 연산자, 동등성 연산자, 이진 비트 연산자, 이진 논리 연산자, 할당 연산자, 쉼표 연산자가 포함됩니다.

대규모 ECMAScript 프로그램은 모듈을 통해 지원되며, 프로그램을 여러 문(statement) 및 선언(declaration) 시퀀스로 분할할 수 있습니다. 각 모듈은 다른 모듈에서 제공되어야 할 선언과, 다른 모듈에서 사용할 수 있는 자신의 선언을 명시적으로 식별합니다.

ECMAScript 문법은 의도적으로 Java 문법과 유사하게 설계되었습니다. ECMAScript 문법은 쉽게 사용할 수 있는 스크립트 언어가 되도록 완화되어 있습니다. 예를 들어, 변수는 타입 선언이 필요하지 않으며, 프로퍼티에 타입이 연결되지 않고, 정의된 함수도 호출보다 먼저 선언될 필요가 없습니다.

4.3.1 객체

ECMAScript에는 클래스 정의 구문이 포함되어 있지만, ECMAScript 객체는 C++, Smalltalk, Java와 같은 언어의 객체처럼 근본적으로 클래스 기반이 아닙니다. 대신, 객체는 리터럴 표기법이나 생성자를 통해 여러 방식으로 생성될 수 있으며, 생성자는 객체를 생성한 후 초기 값을 프로퍼티에 할당하여 객체 전체 또는 일부를 초기화하는 코드를 실행합니다. 각 생성자"prototype"이라는 프로퍼티를 가지는 함수로, 프로토타입 기반 상속공유 프로퍼티를 구현합니다. 객체는 new 표현식에서 생성자를 사용하여 생성됩니다. 예를 들어, new Date(2009, 11)은 새로운 Date 객체를 생성합니다. new 없이 생성자를 호출하면, 그 결과는 생성자에 따라 다릅니다. 예를 들어, Date()는 객체가 아니라 현재 날짜와 시간의 문자열 표현을 반환합니다.

생성자로 생성된 모든 객체는 암시적 참조(객체의 프로토타입이라 함)를 가지며, 이는 해당 생성자"prototype" 프로퍼티 값입니다. 또한, 프로토타입은 자신의 프로토타입에 대한 null이 아닌 암시적 참조를 가질 수 있습니다. 이를 프로토타입 체인이라고 합니다. 객체의 프로퍼티에 대한 참조가 이루어지면, 해당 참조는 프로토타입 체인에서 그 이름의 프로퍼티를 가진 첫 번째 객체의 프로퍼티에 대한 참조입니다. 즉, 먼저 직접 언급된 객체에서 프로퍼티를 찾고, 해당 객체에 프로퍼티가 있으면 그 프로퍼티를 참조하며, 없다면 그 객체의 프로토타입을 다음으로 검사합니다.

그림 1: 객체/프로토타입 관계
상자와 화살표가 많은 이미지.

클래스 기반 객체 지향 언어에서는 일반적으로 상태는 인스턴스가, 메서드는 클래스가 가지며, 상속은 구조와 동작에만 적용됩니다. ECMAScript에서는 상태와 메서드가 객체에 포함되며, 구조, 동작, 상태 모두 상속됩니다.

프로토타입에 특정 프로퍼티가 있지만 직접 해당 프로퍼티를 가지지 않는 모든 객체는 그 프로퍼티와 값을 공유합니다. 그림 1은 이를 보여줍니다:

CF생성자(그리고 객체)입니다. new 표현식을 통해 5개 객체가 생성되었습니다: cf1, cf2, cf3, cf4, cf5. 각 객체는 "q1""q2"라는 프로퍼티를 가집니다. 점선은 암시적 프로토타입 관계를 나타냅니다. 예를 들어, cf3의 프로토타입은 CFp입니다. 생성자 CF는 두 개의 프로퍼티("P1", "P2")를 가지지만, CFp, cf1, cf2, cf3, cf4, cf5에서는 볼 수 없습니다. CFp"CFP1" 프로퍼티는 cf1, cf2, cf3, cf4, cf5에서 공유되며(CF에서는 공유되지 않음), CFp의 암시적 프로토타입 체인에서 "q1", "q2", "CFP1"이 아닌 다른 프로퍼티도 마찬가지로 공유됩니다. CFCFp 사이에는 암시적 프로토타입 링크가 없습니다.

대부분의 클래스 기반 객체 언어와 달리, 객체에는 값을 할당하여 동적으로 프로퍼티를 추가할 수 있습니다. 즉, 생성자는 생성된 객체의 모든 프로퍼티를 반드시 명명하거나 값을 할당할 필요가 없습니다. 위 다이어그램에서 cf1, cf2, cf3, cf4, cf5에 대해 CFp에 새 값을 할당하여 새로운 공유 프로퍼티를 추가할 수 있습니다.

ECMAScript 객체는 본질적으로 클래스 기반은 아니지만, 공통된 생성자 함수, 프로토타입 객체, 메서드 패턴에 기반하여 클래스와 유사한 추상화를 정의하는 것이 편리한 경우가 많습니다. ECMAScript 내장 객체 자체도 이러한 클래스와 유사한 패턴을 따릅니다. ECMAScript 2015부터 ECMAScript 언어에는 내장 객체가 사용하는 클래스와 유사한 추상화 패턴에 맞는 객체를 간결하게 정의할 수 있는 문법적 클래스 정의가 포함되어 있습니다.

4.3.2 ECMAScript의 엄격 변형(strict variant)

ECMAScript 언어는 일부 사용자가 언어의 일부 기능 사용을 제한하고자 할 수도 있음을 인식합니다. 이는 보안, 오류 발생 가능성이 높은 기능 회피, 향상된 오류 검사, 기타 이유 등으로 이루어질 수 있습니다. 이를 지원하기 위해, ECMAScript는 엄격 변형(strict variant)을 정의합니다. 엄격 변형은 일반 ECMAScript 언어의 일부 구문적·의미론적 기능을 제외하고, 일부 기능의 상세 의미론을 수정합니다. 엄격 변형에서는 비엄격(non-strict) 언어 형태에서는 오류로 지정되지 않은 상황에서도 오류 예외를 던져야 하는 추가 오류 조건도 지정합니다.

ECMAScript의 엄격 변형은 일반적으로 언어의 엄격 모드(strict mode)라고 불립니다. 엄격 모드 선택 및 엄격 모드 구문과 의미론 사용은 ECMAScript 소스 텍스트 단위 수준에서 명시적으로 이루어지며, 이는 11.2.2에서 설명되어 있습니다. 엄격 모드는 구문 소스 텍스트 단위 수준에서 선택되므로, 엄격 모드는 해당 소스 텍스트 단위 내에서만 국지적으로 적용되는 제한을 부과합니다. 엄격 모드는 여러 소스 텍스트 단위에 걸쳐 일관되게 동작해야 하는 ECMAScript 의미론의 어떤 측면도 제한하거나 수정하지 않습니다. 완전한 ECMAScript 프로그램은 엄격 모드 및 비엄격 모드 ECMAScript 소스 텍스트 단위를 모두 포함할 수 있습니다. 이 경우, 실제로 엄격 모드 소스 텍스트 단위 내에서 정의된 코드를 실행할 때만 엄격 모드가 적용됩니다.

이 명세를 준수하려면, ECMAScript 구현체는 이 명세에서 정의된 전체 제한 없는 ECMAScript 언어와 엄격 변형 ECMAScript 언어를 모두 구현해야 합니다. 또한, 구현체는 제한 없는 소스 텍스트 단위와 엄격 모드 소스 텍스트 단위를 하나의 복합 프로그램으로 결합하는 것도 지원해야 합니다.

4.4 용어 및 정의

이 문서의 목적상, 다음 용어와 정의가 적용됩니다.

4.4.1 implementation-approximated

implementation-approximated 기능은 외부 소스에 의해 전체 또는 일부가 정의되지만, 이 명세서에서 권장되는 이상적인 동작을 가집니다.

4.4.2 implementation-defined

implementation-defined 기능은 이 명세서 외부의 소스에 의해 전체 또는 일부가 정의됩니다.

4.4.3 host-defined

implementation-defined와 동일합니다.

참고

편집상, 4.2 절을 참고하세요.

4.4.4 type

6 절에서 정의된 데이터 값 집합

4.4.5 primitive value

Undefined, Null, Boolean, Number, BigInt, Symbol, String 타입 중 하나의 멤버로, 6 절에서 정의됨

참고

프리미티브 값은 언어 구현의 가장 낮은 수준에서 직접적으로 표현되는 데이터입니다.

4.4.6 object

Object 타입의 멤버

참고

객체는 프로퍼티의 집합이며 단일 프로토타입 객체를 가집니다. 프로토타입은 null일 수 있습니다.

4.4.7 constructor

객체를 생성하고 초기화하는 함수 객체

참고

constructor"prototype" 프로퍼티 값은 상속과 공유 프로퍼티를 구현하는 프로토타입 객체입니다.

4.4.8 prototype

다른 객체에 공유 프로퍼티를 제공하는 객체

참고

constructor가 객체를 생성하면, 그 객체는 프로퍼티 참조를 해결하기 위해 constructor"prototype" 프로퍼티를 암시적으로 참조합니다. constructor"prototype" 프로퍼티는 프로그램 표현식 constructor.prototype으로 참조할 수 있습니다. 객체의 프로토타입에 프로퍼티를 추가하면, 그 프로토타입을 공유하는 모든 객체가 상속을 통해 해당 프로퍼티를 공유합니다. 또는, Object.create 내장 함수를 사용하여 명시적으로 지정된 프로토타입으로 새 객체를 생성할 수도 있습니다.

4.4.9 ordinary object

모든 객체가 지원해야 하는 필수 내부 메서드에 대해 기본 동작을 가지는 객체

4.4.10 exotic object

필수 내부 메서드 중 하나 이상에 대해 기본 동작을 가지지 않는 객체

참고

ordinary object가 아닌 모든 객체는 exotic object입니다.

4.4.11 standard object

이 명세서에서 의미론이 정의된 객체

4.4.12 built-in object

ECMAScript 구현체에 의해 명세되고 제공되는 객체

참고

표준 내장 객체는 이 명세서에서 정의되어 있습니다. ECMAScript 구현체는 추가 내장 객체 종류를 명세하고 제공할 수 있습니다.

4.4.13 undefined value

변수가 값이 할당되지 않았을 때 사용되는 프리미티브 값

4.4.14 Undefined type

유일한 값이 undefined인 타입

4.4.15 null value

어떤 객체 값도 의도적으로 존재하지 않음을 나타내는 프리미티브 값

4.4.16 Null type

유일한 값이 null인 타입

4.4.17 Boolean value

Boolean type의 멤버

참고

Boolean 값은 truefalse 단 두 가지입니다.

4.4.18 Boolean type

truefalse 프리미티브 값으로 구성된 타입

4.4.19 Boolean object

표준 내장 Boolean 생성자의 인스턴스인 Object type의 멤버

참고

Boolean 객체는 new 표현식에서 Boolean 생성자를 사용하여 Boolean 값을 인자로 전달하여 생성됩니다. 결과 객체는 Boolean 값을 가지는 내부 슬롯을 갖습니다. Boolean 객체는 Boolean 값으로 강제 변환될 수 있습니다.

4.4.20 String value

finite 16비트 부호 없는 integer 값의 0개 이상의 순서 있는 시퀀스인 프리미티브 값

참고

문자열 값은 String type의 멤버입니다. 시퀀스 내 각 integer 값은 일반적으로 UTF-16 텍스트의 16비트 단위를 나타냅니다. 그러나 ECMAScript는 값에 대해 16비트 부호 없는 integer이어야 한다는 것 외에는 제한이나 요구사항을 두지 않습니다.

4.4.21 String type

모든 가능한 문자열 값의 집합

4.4.22 String object

표준 내장 String 생성자의 인스턴스인 Object type의 멤버

참고

문자열 객체는 new 표현식에서 String 생성자를 사용하여 문자열 값을 인자로 전달하여 생성됩니다. 결과 객체는 문자열 값을 가지는 내부 슬롯을 갖습니다. 문자열 객체는 String 생성자를 함수로 호출하여 문자열 값으로 강제 변환할 수 있습니다 (22.1.1.1).

4.4.23 Number value

프리미티브 값으로, IEEE 754-2019 값에 해당하는 배정밀도 64비트 이진 형식 값

참고

숫자 값은 Number type의 멤버이며, 숫자의 직접적인 표현입니다.

4.4.24 Number type

NaN(“not a number”), +∞𝔽(양의 무한대), -∞𝔽(음의 무한대)을 포함한 모든 가능한 Number 값의 집합

4.4.25 Number object

표준 내장 Number 생성자의 인스턴스인 Object type의 멤버

참고

Number 객체는 new 표현식에서 Number 생성자를 사용하여 숫자 값을 인자로 전달하여 생성됩니다. 결과 객체는 숫자 값을 가지는 내부 슬롯을 갖습니다. Number 객체는 Number 생성자를 함수로 호출하여 숫자 값으로 강제 변환할 수 있습니다 (21.1.1.1).

4.4.26 Infinity

양의 무한대 숫자 값

4.4.27 NaN

IEEE 754-2019 NaN(“not a number”) 값인 숫자 값

4.4.28 BigInt value

임의 정밀도의 integer 값에 해당하는 프리미티브 값

4.4.29 BigInt type

모든 가능한 BigInt 값의 집합

4.4.30 BigInt object

표준 내장 BigInt 생성자의 인스턴스인 Object type의 멤버

4.4.31 Symbol value

고유하며, 문자열이 아닌 객체 프로퍼티 키를 나타내는 프리미티브 값

4.4.32 Symbol type

모든 가능한 심볼 값의 집합

4.4.33 Symbol object

표준 내장 Symbol 생성자의 인스턴스인 Object type의 멤버

4.4.34 function

서브루틴으로 호출될 수 있는 Object type의 멤버

참고

함수는 자신의 프로퍼티 외에도, 호출될 때 동작을 결정하는 실행 코드와 상태를 포함합니다. 함수의 코드는 ECMAScript로 작성되었을 수도 있고 아닐 수도 있습니다.

4.4.35 built-in function

함수인 내장 객체

참고

내장 함수의 예로 parseIntMath.exp가 있습니다. 호스트 또는 구현체는 이 명세서에 기술되지 않은 추가 내장 함수를 제공할 수 있습니다.

4.4.36 built-in constructor

생성자인 내장 함수

참고

내장 생성자의 예로 ObjectFunction이 있습니다. 호스트 또는 구현체는 이 명세서에 기술되지 않은 추가 내장 생성자를 제공할 수 있습니다.

4.4.37 property

키(String 값 또는 Symbol 값)와 값을 연결하는 객체의 일부

참고

프로퍼티의 형태에 따라 값은 데이터 값(프리미티브 값, 객체 또는 함수 객체)으로 직접 표현되거나, 접근자 함수 쌍으로 간접적으로 표현될 수 있습니다.

4.4.38 method

프로퍼티 값인 함수

참고

함수가 객체의 메서드로 호출될 때, 해당 객체는 함수의 this 값으로 전달됩니다.

4.4.39 built-in method

내장 함수인 메서드

참고

표준 내장 메서드는 이 명세서에서 정의되어 있습니다. 호스트 또는 구현체는 이 명세서에 기술되지 않은 추가 내장 메서드를 제공할 수 있습니다.

4.4.40 attribute

프로퍼티의 특성을 정의하는 내부 값

4.4.41 own property

해당 객체에 직접 포함된 프로퍼티

4.4.42 inherited property

객체의 프로퍼티 중 직접 포함된 것이 아니지만, 객체의 프로토타입(직접 또는 상속된)에 있는 프로퍼티

4.5 이 명세의 구성

이 명세의 나머지 부분은 다음과 같이 구성되어 있습니다:

5절에서는 명세 전체에서 사용되는 표기 관례를 정의합니다.

6절부터 10절까지는 ECMAScript 프로그램이 동작하는 실행 환경을 정의합니다.

11절부터 17절까지는 모든 언어 기능의 구문적 인코딩과 실행 의미론을 포함하여 실제 ECMAScript 프로그래밍 언어를 정의합니다.

18절부터 28절까지는 ECMAScript 표준 라이브러리를 정의합니다. 여기에는 ECMAScript 프로그램이 실행 시 사용할 수 있는 모든 표준 객체의 정의가 포함됩니다.

29절에서는 SharedArrayBuffer 기반 메모리의 접근 및 Atomics 객체 메서드의 메모리 일관성 모델을 설명합니다.

5 표기 규칙

5.1 구문 및 렉시컬 문법

5.1.1 문맥 자유 문법

문맥 자유 문법은 여러 개의 생산으로 구성됩니다. 각 생산은 비단말 기호라는 추상적인 기호를 왼쪽에 가지고, 0개 이상의 비단말 및 단말 기호오른쪽에 나열합니다. 각 문법에서 단말 기호는 지정된 알파벳에서 가져옵니다.

연쇄 생산이란 오른쪽에 정확히 하나의 비단말 기호와 0개 이상의 단말 기호만을 가지는 생산을 말합니다.

특정 문맥 자유 문법은 목표 기호라 불리는 하나의 구별된 비단말로 구성된 문장에서 시작하여, 시퀀스 내의 아무 비단말이나 그 비단말이 왼쪽이 되는 생산의 오른쪽으로 반복적으로 대체함으로써 결과적으로 생성할 수 있는 단말 기호의 모든 가능한 시퀀스 집합(언어)을 지정합니다. 이 집합은 유한하거나 무한할 수 있습니다.

5.1.2 렉시컬 및 정규식 문법

ECMAScript의 렉시컬 문법12절에 제공됩니다. 이 문법의 단말 기호는 SourceCharacter에서 정의된 규칙에 따라 Unicode 코드 포인트입니다(11.1 참조). 이 문법은 목표 기호 InputElementDiv, InputElementTemplateTail, InputElementRegExp, InputElementRegExpOrTemplateTail, InputElementHashbangOrRegExp 등에서 시작하여, 이러한 코드 포인트 시퀀스가 입력 요소 시퀀스로 번역되는 방식을 정의합니다.

공백 문자와 주석을 제외한 입력 요소는 ECMAScript의 구문 문법의 단말 기호가 되며, 이를 ECMAScript 토큰이라 부릅니다. 이 토큰들은 예약어, 식별자, 리터럴, ECMAScript 언어의 구분자입니다. 또한, 줄 종결자는 토큰으로 간주되지 않지만 입력 요소 스트림의 일부가 되어 자동 세미콜론 삽입 과정(12.10)을 안내합니다. 단순 공백 및 한 줄 주석은 버려지며, 구문 문법을 위한 입력 요소 스트림에는 나타나지 않습니다. MultiLineComment(즉, 여러 줄에 걸쳐 있을 수 있는 /**/ 형태의 주석)는 줄 종결자가 없으면 단순히 버려집니다. 그러나 MultiLineComment가 하나 이상의 줄 종결자를 포함하는 경우, 단일 줄 종결자로 대체되어 구문 문법을 위한 입력 요소 스트림의 일부가 됩니다.

ECMAScript의 정규식 문법22.2.1에 제공됩니다. 이 문법 역시 SourceCharacter로 정의된 코드 포인트를 단말 기호로 사용합니다. 이 문법은 목표 기호 Pattern에서 시작하여, 코드 포인트 시퀀스가 정규식 패턴으로 변환되는 방법을 설명합니다.

렉시컬 및 정규식 문법의 생산은 구분 기호로 두 개의 콜론 “::”을 사용하여 구분됩니다. 렉시컬 문법과 정규식 문법은 일부 생산을 공유합니다.

5.1.3 숫자 문자열 문법

숫자 문자열 문법7.1.4.1에서 나타납니다. 이 문법은 SourceCharacter를 단말 기호로 사용하며, 목표 기호 StringNumericLiteral에서 시작하여 문자열을 숫자 값으로 변환하는 데 사용됩니다(이는 숫자 리터럴의 렉시컬 문법과 유사하지만 다릅니다).

숫자 문자열 문법의 생산은 세 개의 콜론 “:::”으로 구분되며, 소스 텍스트 파싱에는 절대 사용되지 않습니다.

5.1.4 구문 문법

ECMAScript의 구문 문법13부터 16까지의 절에 제공됩니다. 이 문법은 렉시컬 문법에서 정의된 ECMAScript 토큰을 단말 기호로 사용합니다(5.1.2). 목표 기호 ScriptModule에서 시작하여, 토큰 시퀀스가 ECMAScript 프로그램의 구문적으로 올바른 독립 구성 요소를 형성하는 방법을 설명합니다.

코드 포인트 스트림을 ECMAScript Script 또는 Module로 파싱할 때, 먼저 렉시컬 문법을 반복적으로 적용하여 입력 요소 스트림으로 변환합니다. 그 후 이 입력 요소 스트림을 단일 구문 문법 적용으로 파싱합니다. 입력 스트림의 토큰들이 목표 비단말(Script 또는 Module)의 단일 인스턴스로 파싱될 수 없거나 토큰이 남아 있다면 구문 오류입니다.

파싱에 성공하면, 파싱 트리라는 루트가 있는 트리 구조를 생성합니다. 각 노드는 파싱 노드입니다. 각 파싱 노드는 문법 기호의 인스턴스이며, 해당 기호로부터 유도될 수 있는 소스 텍스트의 범위를 나타냅니다. 파싱 트리의 루트 노드(소스 텍스트 전체를 나타냄)는 파싱의 목표 기호의 인스턴스입니다. 파싱 노드가 비단말의 인스턴스인 경우, 그 비단말을 왼쪽으로 하는 생산의 인스턴스이기도 합니다. 또한, 오른쪽에 있는 각 기호마다 0개 이상의 자식을 가지며, 각 자식은 해당 기호의 파싱 노드 인스턴스입니다.

새로운 파싱 노드는 파서 호출마다 인스턴스화되며 동일한 소스 텍스트라도 파싱 간에는 재사용되지 않습니다. 파싱 노드는 동일한 소스 텍스트 범위를 나타내고, 동일한 문법 기호의 인스턴스이며, 동일한 파서 호출에서 생성된 경우에만 동일한 파싱 노드로 간주됩니다.

참고 1

동일한 문자열을 여러 번 파싱하면 서로 다른 파싱 노드가 생성됩니다. 예를 들어,

let str = "1 + 1;";
eval(str);
eval(str);

eval 호출은 str의 값을 ECMAScript 소스 텍스트로 변환하고, 각기 독립적으로 파싱하여 별도의 파싱 노드 트리를 생성합니다. 각 파싱은 동일한 문자열 값에서 유래했더라도 트리는 서로 다릅니다.

참고 2
파싱 노드는 명세상의 산물이며, 구현체는 유사한 데이터 구조를 사용할 필요는 없습니다.

구문 문법의 생산은 구분 기호로 하나의 콜론 “:”만을 사용합니다.

13부터 16까지 제시된 구문 문법은 ECMAScript Script 또는 Module에 대해 허용되는 토큰 시퀀스의 완전한 설명이 아닙니다. 특정 추가 토큰 시퀀스도 허용되는데, 이는 특정 위치(예: 줄 종결자 앞)에 세미콜론만 추가하면 문법에서 설명될 수 있는 시퀀스입니다. 또한, 문법에서 설명된 일부 토큰 시퀀스는 특정 “어색한” 위치에 줄 종결자가 나타나면 허용되지 않습니다.

특정 경우, 모호성을 피하기 위해 구문 문법은 유효한 ECMAScript Script 또는 Module를 형성하지 않는 토큰 시퀀스도 허용하는 일반화된 생산을 사용합니다. 예를 들어, 객체 리터럴 및 객체 구조 분해 패턴에서 이 기법이 사용됩니다. 이러한 경우, 허용되는 토큰 시퀀스를 더욱 제한하는 보조 문법이 제공됩니다. 일반적으로 조기 오류 규칙은 특정 문맥에서 "PN포함해야 한다"라고 명시합니다. 여기서 P는 일반화된 생산의 파싱 노드 인스턴스이며 N은 보조 문법의 비단말입니다. 이는 다음을 의미합니다:

  1. P가 원래 매칭한 토큰 시퀀스를 N목표 기호로 하여 다시 파싱합니다. N이 문법 파라미터를 가지면, P가 원래 파싱될 때와 동일한 값으로 설정합니다.
  2. 토큰 시퀀스가 N의 단일 인스턴스로 파싱될 수 있고, 토큰이 남지 않으면:
    1. 해당 P에 대해 고유한 N 인스턴스를 "P포함하는 N”이라고 부릅니다.
    2. N 및 그 파생 생산에 대한 모든 조기 오류 규칙은 P가 포함하는 N에도 적용됩니다.
  3. 그렇지 않으면(파싱이 실패하면) 조기 문법 오류입니다.

5.1.5 문법 표기법

5.1.5.1 단말 기호

ECMAScript 문법에서 일부 단말 기호는 고정폭 글꼴로 표시됩니다. 이러한 기호는 소스 텍스트에 정확히 작성된 대로 나타나야 합니다. 이 방식으로 지정된 모든 단말 기호 코드 포인트는 기본 라틴 블록의 적절한 Unicode 코드 포인트로 이해되어야 하며, 다른 Unicode 범위의 유사한 코드 포인트와는 다릅니다. 단말 기호의 코드 포인트는 \ UnicodeEscapeSequence로 표현할 수 없습니다.

단말 기호가 개별 Unicode 코드 포인트인 문법(즉, 렉시컬, 정규식, 숫자 문자열 문법)에서, 생산 내 여러 고정폭 코드 포인트가 연속적으로 나타나는 것은 동일한 시퀀스의 코드 포인트를 각각 독립된 단말 기호로 작성하는 것에 대한 간단한 약어입니다.

예를 들어, 다음 생산:

HexIntegerLiteral :: 0x HexDigits

는 다음과 같은 약어입니다:

HexIntegerLiteral :: 0 x HexDigits

반대로, 구문 문법에서는 고정폭 코드 포인트가 연속적으로 나타나면 하나의 단일 단말 기호입니다.

단말 기호는 다음 두 가지 형태도 있습니다:

  • 렉시컬 및 정규식 문법에서는 일반적으로 인쇄되는 표현이 없는 Unicode 코드 포인트가 대신 "<ABBREV>" 형태로 표시되며, "ABBREV"는 해당 코드 포인트 또는 코드 포인트 집합을 위한 기억법입니다. 이러한 형태는 유니코드 포맷-컨트롤 문자, 공백 문자, 줄 종결자에서 정의됩니다.
  • 구문 문법에서는 특정 단말 기호(예: IdentifierName, RegularExpressionLiteral)는 이탤릭체로 나타나는데, 이는 해당 이름의 비단말을 렉시컬 문법에서 참조하기 때문입니다.

5.1.5.2 비단말 기호 및 생산

비단말 기호는 이탤릭체로 표시됩니다. 비단말의 정의(생산이라고도 함)는 정의되는 비단말의 이름 뒤에 하나 이상의 콜론이 붙어 도입됩니다. (콜론의 개수는 해당 생산이 속하는 문법을 나타냅니다.) 비단말의 하나 이상의 대체 오른쪽 부분이 뒤따라 나열됩니다. 예를 들어, 구문 정의는 다음과 같습니다:

WhileStatement : while ( Expression ) Statement

이 정의는 WhileStatement 비단말이 while 토큰, 이어서 왼쪽 괄호 토큰, 이어서 Expression, 이어서 오른쪽 괄호 토큰, 이어서 Statement를 나타냄을 의미합니다. ExpressionStatement는 각각 비단말입니다. 또 다른 예시로, 구문 정의는 다음과 같습니다:

ArgumentList : AssignmentExpression ArgumentList , AssignmentExpression

이 정의는 ArgumentList가 하나의 AssignmentExpression 또는 ArgumentList 뒤에 쉼표, 그리고 AssignmentExpression가 올 수 있음을 의미합니다. 이 ArgumentList 정의는 재귀적이며, 자기 자신을 기준으로 정의됩니다. 결과적으로 ArgumentList는 쉼표로 구분된 임의의 개수의 인수를 포함할 수 있으며, 각 인수 식은 AssignmentExpression 입니다. 이러한 비단말의 재귀적 정의는 흔합니다.

5.1.5.3 선택적 기호

단말 또는 비단말 뒤에 나타날 수 있는 아래첨자 접미사 “opt”는 선택적 기호임을 나타냅니다. 선택적 기호가 포함된 대안은 실제로 선택적 요소를 생략한 오른쪽과 포함한 오른쪽의 두 가지를 지정합니다. 이는 다음을 의미합니다:

VariableDeclaration : BindingIdentifier Initializeropt

는 다음과 같은 편리한 약어입니다:

VariableDeclaration : BindingIdentifier BindingIdentifier Initializer

그리고 다음과 같습니다:

ForStatement : for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement

는 다음과 같은 편리한 약어입니다:

ForStatement : for ( LexicalDeclaration ; Expressionopt ) Statement for ( LexicalDeclaration Expression ; Expressionopt ) Statement

이는 다시 다음과 같은 약어입니다:

ForStatement : for ( LexicalDeclaration ; ) Statement for ( LexicalDeclaration ; Expression ) Statement for ( LexicalDeclaration Expression ; ) Statement for ( LexicalDeclaration Expression ; Expression ) Statement

즉, 이 예시에서 ForStatement 비단말은 실제로 네 가지 대안 오른쪽을 가집니다.

5.1.5.4 문법 파라미터

생산은 아래첨자 주석 "[parameters]" 형태로 파라미터화될 수 있으며, 이는 생산에서 정의된 비단말 기호의 접미사로 나타날 수 있습니다. “parameters”는 하나의 이름 또는 쉼표로 구분된 이름 목록일 수 있습니다. 파라미터화된 생산은 해당 파라미터 이름의 모든 조합에 대한 생산 집합을 나타내는 약어로, 파라미터화된 비단말 기호 뒤에 언더스코어와 함께 붙여집니다. 이는 다음을 의미합니다:

StatementList[Return] : ReturnStatement ExpressionStatement

는 다음과 같은 편리한 약어입니다:

StatementList : ReturnStatement ExpressionStatement StatementList_Return : ReturnStatement ExpressionStatement

그리고 다음과 같습니다:

StatementList[Return, In] : ReturnStatement ExpressionStatement

는 다음과 같은 약어입니다:

StatementList : ReturnStatement ExpressionStatement StatementList_Return : ReturnStatement ExpressionStatement StatementList_In : ReturnStatement ExpressionStatement StatementList_Return_In : ReturnStatement ExpressionStatement

여러 파라미터는 조합적으로 많은 생산을 생성하며, 이들 모두가 반드시 완전한 문법에서 참조되는 것은 아닙니다.

생산의 오른쪽에 있는 비단말 참조 역시 파라미터화될 수 있습니다. 예를 들어:

StatementList : ReturnStatement ExpressionStatement[+In]

는 다음과 동일합니다:

StatementList : ReturnStatement ExpressionStatement_In

그리고 다음과 같습니다:

StatementList : ReturnStatement ExpressionStatement[~In]

는 다음과 동일합니다:

StatementList : ReturnStatement ExpressionStatement

비단말 참조는 파라미터 목록과 “opt” 접미사를 모두 가질 수 있습니다. 예를 들어:

VariableDeclaration : BindingIdentifier Initializer[+In]opt

는 다음과 같은 약어입니다:

VariableDeclaration : BindingIdentifier BindingIdentifier Initializer_In

오른쪽 비단말 참조에 파라미터 이름 앞에 “?”를 붙이면, 해당 파라미터 값이 현재 생산의 왼쪽 기호 참조에 나타나는 파라미터 이름에 의존함을 의미합니다. 예를 들어:

VariableDeclaration[In] : BindingIdentifier Initializer[?In]

는 다음과 같은 약어입니다:

VariableDeclaration : BindingIdentifier Initializer VariableDeclaration_In : BindingIdentifier Initializer_In

오른쪽 대안에 “[+parameter]”가 접두사로 붙으면, 해당 대안은 지정된 파라미터가 생산의 비단말 기호 참조에 사용될 때만 사용할 수 있습니다. “[~parameter]”가 접두사로 붙으면, 해당 대안은 지정된 파라미터가 사용되지 않을 때만 사용할 수 있습니다. 이는 다음을 의미합니다:

StatementList[Return] : [+Return] ReturnStatement ExpressionStatement

는 다음과 같은 약어입니다:

StatementList : ExpressionStatement StatementList_Return : ReturnStatement ExpressionStatement

그리고 다음과 같습니다:

StatementList[Return] : [~Return] ReturnStatement ExpressionStatement

는 다음과 같은 약어입니다:

StatementList : ReturnStatement ExpressionStatement StatementList_Return : ExpressionStatement

5.1.5.5 one of

문법 정의에서 콜론 뒤에 “one of”가 나오면, 다음 줄 또는 줄들에 있는 각 단말 기호가 대안 정의임을 나타냅니다. 예를 들어, ECMAScript의 렉시컬 문법에는 다음과 같은 생산이 있습니다:

NonZeroDigit :: one of 1 2 3 4 5 6 7 8 9

이는 다음과 같은 간편한 약어입니다:

NonZeroDigit :: 1 2 3 4 5 6 7 8 9

5.1.5.6 [empty]

생산의 오른쪽에 “[empty]”라는 문구가 나타나면, 해당 생산의 오른쪽에 단말 또는 비단말이 없음을 나타냅니다.

5.1.5.7 전방 탐색 제한

생산의 오른쪽에 “[lookahead = seq]” 문구가 나타나면, 해당 생산은 토큰 시퀀스 seq가 즉시 뒤따르는 입력 토큰 시퀀스의 접두사인 경우에만 사용할 수 있음을 나타냅니다. 마찬가지로 “[lookahead ∈ set]”에서 set유한하고 비어 있지 않은 토큰 시퀀스 집합일 때, 해당 생산은 집합의 일부 요소가 즉시 뒤따르는 토큰 시퀀스의 접두사인 경우에만 사용할 수 있음을 나타냅니다. 편의를 위해 집합을 비단말로도 쓸 수 있는데, 이 경우 해당 비단말이 확장될 수 있는 모든 토큰 시퀀스의 집합을 나타냅니다. 만약 비단말이 무한히 많은 토큰 시퀀스로 확장될 수 있다면 이는 편집상 오류로 간주됩니다.

이 조건들은 부정될 수 있습니다. “[lookahead ≠ seq]”는 seq가 즉시 뒤따르는 입력 토큰 시퀀스의 접두사가 아닌 경우에만 해당 생산을 사용할 수 있음을 나타내며, “[lookahead ∉ set]”는 어느 요소도 즉시 뒤따르는 토큰 시퀀스의 접두사가 아닌 경우에만 해당 생산을 사용할 수 있음을 나타냅니다.

예시로, 다음 정의가 주어졌을 때:

DecimalDigit :: one of 0 1 2 3 4 5 6 7 8 9 DecimalDigits :: DecimalDigit DecimalDigits DecimalDigit

다음과 같은 정의에서:

LookaheadExample :: n [lookahead ∉ { 1, 3, 5, 7, 9 }] DecimalDigits DecimalDigit [lookahead ∉ DecimalDigit]

이 정의는 n 문자 뒤에 하나 이상의 십진수 숫자가 오는데, 첫 번째 숫자가 짝수인 경우, 또는 십진수 숫자가 뒤에 다른 십진수 숫자가 오지 않는 경우를 매칭합니다.

이러한 문구가 구문 문법에서 사용될 때는, 즉시 뒤따르는 토큰 시퀀스를 명확하게 식별하는 것이 불가능할 수 있습니다. 이후 토큰을 결정하려면 이후 위치에서 사용할 렉시컬 목표 기호를 알아야 하기 때문입니다. 따라서 구문 문법에서 이러한 제한이 사용될 때, 토큰 시퀀스 seq가 전방 탐색 제한에(집합의 일부로 포함되는 경우 포함하여) 나타나고, 사용되는 렉시컬 목표 기호의 선택에 따라 seq가 결과 토큰 시퀀스의 접두사가 될 수 있는지 여부가 달라진다면, 이는 편집상 오류로 간주됩니다.

5.1.5.8 [여기 LineTerminator 없음]

구문 문법의 생산 오른쪽에 “[여기 LineTerminator 없음]”이라는 문구가 나타나면, 해당 생산은 제한된 생산임을 의미합니다. 즉, 입력 스트림의 지정된 위치에 LineTerminator가 발생하면 사용할 수 없습니다. 예를 들어, 다음 생산:

ThrowStatement : throw [여기 LineTerminator 없음] Expression ;

이 생산은 throw 토큰과 Expression 사이에 LineTerminator가 스크립트에 있으면 사용할 수 없음을 나타냅니다.

제한된 생산에 의해 LineTerminator의 존재가 금지되지 않는 한, 입력 요소 스트림 내의 연속된 두 토큰 사이에는 임의의 개수의 LineTerminator가 있어도 스크립트의 구문적 허용성에는 영향을 주지 않습니다.

5.1.5.9 but not

생산의 오른쪽에 “but not” 문구를 사용하여, 확장 중 특정 경우를 허용하지 않음을 지정할 수 있습니다. 예를 들어, 다음 생산:

Identifier :: IdentifierName but not ReservedWord

이 정의는 Identifier 비단말이 IdentifierName로 대체될 수 있으나, 같은 코드 포인트 시퀀스가 ReservedWord로도 대체될 수 있다면 허용되지 않음을 의미합니다.

5.1.5.10 설명적 문구

마지막으로, 경우에 따라 모든 대안을 나열하는 것이 비현실적일 때 몇몇 비단말 기호는 산세리프체 설명 문구로 서술됩니다:

SourceCharacter :: 모든 Unicode 코드 포인트

5.2 알고리즘 규칙

명세에서는 종종 번호가 매겨진 목록을 사용하여 알고리즘의 단계를 지정합니다. 이러한 알고리즘은 ECMAScript 언어 구성 요소의 필수 의미를 정확히 명시하는 데 사용됩니다. 이 알고리즘들은 특정 구현 기법의 사용을 암시하려는 의도가 아닙니다. 실제로는 주어진 기능을 구현할 때 더 효율적인 알고리즘이 있을 수 있습니다.

알고리즘은 명시적으로 매개변수화될 수 있으며, 쉼표로 구분된 순서의 별칭 이름 시퀀스를 사용하여, 알고리즘 단계 내에서 해당 위치에 전달된 인수를 참조할 수 있습니다. 선택적 매개변수는 괄호([ , name ])로 둘러싸여 있으며, 알고리즘 단계 내에서는 필수 매개변수와 다르지 않습니다. 나머지 매개변수(rest parameter)는 매개변수 목록의 끝에 ...name 형태로 나타나며, 필수 및 선택적 매개변수 뒤에 제공된 모든 인수를 List에 담습니다. 추가 인수가 없다면 해당 List는 비어 있습니다.

알고리즘 단계는 순차적 하위 단계로 세분화될 수 있습니다. 하위 단계는 들여쓰기되며, 자체적으로 추가 하위 단계로 나눌 수 있습니다. 개요 번호 규칙에 따라 첫 번째 하위 단계는 소문자 알파벳, 두 번째 하위 단계는 소문자 로마 숫자가 사용됩니다. 세 단계보다 많으면 네 번째 단계는 숫자 라벨을 사용하며, 예시는 다음과 같습니다:

  1. 최상위 단계
    1. 하위 단계.
    2. 하위 단계.
      1. 하위하위 단계.
        1. 하위하위하위 단계
          1. 하위하위하위하위 단계
            1. 하위하위하위하위하위 단계

단계 또는 하위 단계는 “if” 조건문으로 작성되어 그 하위 단계를 조건부로 적용할 수 있습니다. 이 경우, 조건이 참일 때만 하위 단계가 적용됩니다. 단계 또는 하위 단계가 “else”로 시작하면, 같은 수준의 앞선 “if” 조건문의 부정 조건입니다.

단계는 그 하위 단계를 반복적으로 적용한다고 명시할 수 있습니다.

Assert:”로 시작하는 단계는 알고리즘의 불변 조건을 주장합니다. 이러한 주장은 암묵적인 알고리즘적 불변 조건을 명시적으로 드러내기 위해 사용됩니다. 이러한 주장은 추가적인 의미적 요구사항을 부과하지 않으므로 구현체에서 반드시 검사할 필요는 없습니다. 오로지 알고리즘을 명확히 하기 위해 사용됩니다.

알고리즘 단계에서는 “Let x be someValue” 형태로 명명된 별칭(alias)을 선언할 수 있습니다. 이 별칭은 참조처럼 동작하여 xsomeValue 모두 동일한 데이터 기반을 참조하며, 둘 중 하나를 변경하면 모두에게 반영됩니다. 참조와 같은 동작을 피하고 싶다면 “Let x be a copy of someValue”처럼 오른쪽 값을 복사하도록 명시해야 하며, 이는 someValue의 얕은 복사본을 생성합니다.

한 번 선언된 별칭은 이후 단계에서 참조할 수 있으며, 별칭 선언 이전의 단계에서는 참조해서는 안 됩니다. 별칭은 “Set x to someOtherValue” 형태로 수정할 수 있습니다.

5.2.1 추상 연산

명세의 여러 부분에서 사용될 수 있도록, 일부 알고리즘은 추상 연산이라 불리며, 이름이 붙고 매개변수화된 함수 형태로 작성되어 다른 알고리즘에서 이름으로 참조될 수 있습니다. 추상 연산은 보통 OperationName(arg1, arg2)과 같은 함수 호출 방식으로 참조됩니다. 일부 추상 연산은 클래스와 유사한 명세 추상화의 다형적으로 호출되는 메서드로 취급되기도 합니다. 이러한 메서드형 추상 연산은 일반적으로 someValue.OperationName(arg1, arg2)와 같은 메서드 호출 방식으로 참조됩니다.

5.2.2 구문 지향 연산

구문 지향 연산이란, 하나 이상의 ECMAScript 문법 생산에 연결된 알고리즘으로 구성된 이름 있는 연산입니다. 여러 대안 정의가 있는 생산은 일반적으로 각 대안마다 별도의 알고리즘을 가집니다. 알고리즘이 문법 생산에 연결되면, 해당 대안의 단말 및 비단말 기호를 알고리즘의 매개변수처럼 참조할 수 있습니다. 이 방식에서 비단말 기호는 소스 텍스트를 파싱할 때 실제로 일치한 대안 정의를 참조합니다. 문법 생산이나 그로부터 파생된 파싱 노드가 일치시킨 소스 텍스트란, 일치에 참여한 첫 번째 단말부터 마지막 단말까지의 소스 텍스트 부분을 의미합니다.

알고리즘이 생산 대안에 연결되면, 대안은 일반적으로 “[ ]” 문법 주석 없이 표시됩니다. 이러한 주석은 대안의 구문 인식에만 영향을 주며, 연결된 의미에는 영향을 주지 않습니다.

구문 지향 연산은 파싱 노드와 필요하다면 추가 매개변수를 전달하여, 다음 알고리즘의 1, 3, 4 단계 규칙을 따라 호출됩니다:

  1. Let status be SyntaxDirectedOperation of SomeNonTerminal.
  2. Let someParseNode be the parse of some source text.
  3. Perform SyntaxDirectedOperation of someParseNode.
  4. Perform SyntaxDirectedOperation of someParseNode with argument "value".

명시적으로 달리 지정하지 않는 한, 모든 연쇄 생산은 해당 생산의 왼쪽 비단말에 적용될 수 있는 모든 연산에 대한 암묵적 정의를 가집니다. 암묵적 정의는 동일한 연산을 동일한 매개변수로, 해당 연쇄 생산의 유일한 오른쪽 비단말에 다시 적용한 뒤 그 결과를 반환합니다. 예를 들어, 어떤 알고리즘이 “Return Evaluation of Block” 단계를 가진다고 가정하고, 다음과 같은 생산이 있다고 합시다:

Block : { StatementList }

하지만 Evaluation 연산이 해당 생산에 알고리즘을 연결하지 않았다면, Evaluation 연산은 암묵적으로 다음과 같은 연결을 포함합니다:

런타임 의미: Evaluation

Block : { StatementList }
  1. Return Evaluation of StatementList.

5.2.3 런타임 의미

런타임에 호출되어야 할 의미를 명시하는 알고리즘을 런타임 의미라 합니다. 런타임 의미는 추상 연산이나 구문 지향 연산으로 정의됩니다.

5.2.3.1 Completion ( completionRecord )

추상 연산 Completion은 completionRecord (Completion Record) 인자를 받아 Completion Record를 반환합니다. 이는 Completion Record가 반환됨을 강조할 때 사용됩니다. 다음 단계를 수행합니다:

  1. Assert: completionRecordCompletion Record이다.
  2. completionRecord를 반환한다.

5.2.3.2 예외 던지기

예외를 던지라고 하는 알고리즘 단계, 예:

  1. TypeError 예외를 던진다.

는 다음과 동일한 의미입니다:

  1. Return ThrowCompletion(새롭게 생성된 TypeError 객체).

5.2.3.3 ReturnIfAbrupt

다음과 같은 알고리즘 단계 혹은 동등한 단계:

  1. ReturnIfAbrupt(argument).

는 다음과 동일한 의미입니다:

  1. Assert: argumentCompletion Record이다.
  2. 만약 argumentabrupt completion이면, Completion(argument)를 반환한다.
  3. 그렇지 않으면, argumentargument.[[Value]]로 설정한다.

다음과 같은 알고리즘 단계 혹은 동등한 단계:

  1. ReturnIfAbrupt(AbstractOperation()).

는 다음과 동일한 의미입니다:

  1. hygienicTemp를 AbstractOperation()의 결과로 설정한다.
  2. Assert: hygienicTempCompletion Record이다.
  3. 만약 hygienicTempabrupt completion이면, Completion(hygienicTemp)를 반환한다.
  4. 그렇지 않으면, hygienicTemphygienicTemp.[[Value]]로 설정한다.

hygienicTemp는 ReturnIfAbrupt와 관련된 단계 내에서만 잠시 사용됩니다.

다음과 같은 알고리즘 단계 혹은 동등한 단계:

  1. result를 AbstractOperation(ReturnIfAbrupt(argument))의 결과로 설정한다.

는 다음과 동일한 의미입니다:

  1. Assert: argumentCompletion Record이다.
  2. 만약 argumentabrupt completion이면, Completion(argument)를 반환한다.
  3. 그렇지 않으면, argumentargument.[[Value]]로 설정한다.
  4. result를 AbstractOperation(argument)의 결과로 설정한다.

5.2.3.4 ReturnIfAbrupt 약어

추상 연산구문 지향 연산 호출 앞에 ?가 붙으면, 결과 Completion RecordReturnIfAbrupt를 적용해야 함을 나타냅니다. 예:

  1. ? OperationName().

다음 단계와 동일합니다:

  1. ReturnIfAbrupt(OperationName()).

유사하게, 메서드 호출 방식에서는 다음 단계:

  1. someValue.OperationName().

다음과 동일합니다:

  1. ReturnIfAbrupt(someValue.OperationName()).

유사하게, ! 접두사는 뒤따르는 추상 또는 구문 지향 연산abrupt completion을 반환하지 않고, 결과 Completion Record[[Value]] 필드를 연산의 반환 값으로 사용해야 함을 나타냅니다. 예:

  1. Let val be ! OperationName().

다음 단계와 동일합니다:

  1. Let val be OperationName().
  2. Assert: valnormal completion이다.
  3. valval.[[Value]]로 설정한다.

구문 지향 연산런타임 의미에서 ! 또는 ?를 연산 호출 앞에 붙여 이 약어를 사용합니다:

  1. Perform ! SyntaxDirectedOperation of NonTerminal.

5.2.3.5 암묵적 정상 완료

추상 연산에서 Completion Record를 반환한다고 선언된 알고리즘과 모든 내장 함수에서, 반환값은 먼저 NormalCompletion에 전달되고, 그 결과가 실제로 사용됩니다. 이 규칙은 Completion 알고리즘 내부나, 반환값이 해당 단계에서 명확히 Completion Record로 표시된 경우에는 적용되지 않습니다. 이러한 경우는 다음과 같습니다:

이러한 추상 연산에서 다른 방식으로 Completion Record가 반환되면 편집상 오류입니다. 예를 들어, 이러한 추상 연산 내에서,

  1. Return true.

는 다음과 같은 단계와 동일합니다:

  1. Return NormalCompletion(true).

또는

  1. Let completion be NormalCompletion(true).
  2. Return Completion(completion).

또는

  1. Return Completion Record { [[Type]]: normal, [[Value]]: true, [[Target]]: empty  }.

ReturnIfAbrupt 확장 규칙을 통해, 다음 예시는 허용됩니다. 확장된 단계 내에서는 Completion의 결과가 비정상(abrupt)인 경우 직접 반환되고, 정상(normal)인 경우 언랩 후 암묵적으로 NormalCompletion이 적용됩니다.

  1. Return ? completion.

다음 예시는 Completion Record가 해당 단계에서 명시적으로 표시되지 않고 반환되므로 편집상 오류입니다.

  1. Let completion be NormalCompletion(true).
  2. Return completion.

5.2.4 정적 의미

문맥 자유 문법만으로는 입력 요소 스트림이 평가 가능한 유효한 ECMAScript Script 또는 Module인지 결정하는 모든 규칙을 표현하기에는 충분하지 않습니다. 어떤 상황에서는 ECMAScript 알고리즘 규칙이나 산문적 요구사항으로 표현되는 추가 규칙이 필요합니다. 이러한 규칙은 항상 문법 생산에 연결되며, 해당 생산의 정적 의미라 불립니다.

정적 의미 규칙은 이름을 가지며, 보통 알고리즘으로 정의됩니다. 이름 있는 정적 의미 규칙은 문법 생산에 연결되고, 여러 대안 정의가 있는 생산은 각 대안마다 적용 가능한 이름 있는 정적 의미 규칙에 대해 별도의 알고리즘을 가집니다.

정적 의미 규칙의 특수한 종류가 조기 오류 규칙입니다. 조기 오류 규칙은 특정 문법 생산과 연결된 조기 오류 조건을 정의합니다(17 절 참조). 대부분의 조기 오류 규칙에 대한 Evaluation 호출은 명세 알고리즘 내에서 명시적으로 호출되지 않습니다. 적합한 구현체는 Script 또는 Module을 최초로 평가하기 전에, 해당 Script 또는 Module을 파싱하는 데 사용된 모든 생산의 조기 오류 규칙을 검사해야 합니다. 만약 조기 오류 규칙이 위반되면, 해당 Script 또는 Module은 유효하지 않으며 평가될 수 없습니다.

5.2.5 수학 연산

이 명세에서는 다음과 같은 종류의 수치 값을 참조합니다:

  • 수학적 값: 임의의 실수. 기본 숫자 타입으로 사용됩니다.
  • 확장 수학적 값: 수학적 값과 함께 +∞, -∞를 포함합니다.
  • 숫자(Number): IEEE 754-2019 binary64(배정밀도 부동소수점) 값.
  • BigInt: ECMAScript 언어 값으로 임의의 정수를 일대일로 나타냅니다.

이 명세에서 수치 값은 아래첨자 접미사를 통해 서로 다른 숫자 종류로 구분됩니다. 𝔽는 Number, 는 BigInt를 의미합니다. 접미사가 없는 수치 값은 수학적 값을 의미합니다. 대부분의 수치 값은 10진수로 표기되며, 0x로 시작하는 경우 16진수 값입니다.

일반적으로 명세에서 "the length of y" 또는 "the integer represented by the four hexadecimal digits ..."처럼 숫자 종류를 명시하지 않을 때는 수학적 값을 의미합니다. Number 또는 BigInt 값은 명시적으로 표시됩니다. 예: "the Number value for the number of code points in …" 또는 "the BigInt value for …".

명세에서 정수(integer)란 별도 명시가 없는 한 수학적 값정수 집합에 속하는 값을 의미합니다. 정수(Number)유한 Number 값 중 수학적 값정수 집합에 속하는 값을 의미합니다.

+, ×, =, ≥ 등의 수치 연산자는 피연산자의 타입에 따라 해당 연산을 의미합니다. 수학적 값에 적용하면 일반적인 수학 연산을 의미합니다. 확장 수학적 값에 적용하면 확장 실수에 대한 연산을 의미하며, 결정할 수 없는 형태는 정의되지 않으며 명세에서 사용하면 편집상 오류입니다. Number에 적용하면 IEEE 754-2019의 관련 연산을 의미합니다. BigInt에 적용하면 해당 BigInt의 수학적 값에 대한 일반적인 수학 연산을 의미합니다. 서로 다른 타입의 피연산자(예: Number와 수학적 값)에 적용된 수치 연산자는 정의되지 않으며, 명세에서 사용하면 편집상 오류입니다.

수학적 값과 Number 또는 BigInt 간 변환은 항상 명시적으로 이루어집니다. 수학적 값 또는 확장 수학적 값 x를 Number로 변환하는 것은 "the Number value for x" 또는 𝔽(x)으로 표기하며, 6.1.6.1에서 정의됩니다. 정수 x를 BigInt로 변환하는 것은 "the BigInt value for x" 또는 ℤ(x)으로 표기합니다. Number 또는 BigInt x수학적 값으로 변환하는 것은 "the mathematical value of x" 또는 ℝ(x)으로 표기합니다. mathematical value of +0𝔽-0𝔽수학적 값 0입니다. mathematical value of 비-유한 값은 정의되지 않습니다. extended mathematical value of x유한 값에서는 mathematical value of x와 동일하며, +∞𝔽-∞𝔽에는 +∞, -∞이고, NaN에는 정의되지 않습니다.

수학 함수 abs(x)x의 절대값을 반환하며, x < 0이면 -x, 그렇지 않으면 x 자체입니다.

수학 함수 min(x1, x2, … , xN)x1부터 xN 중 가장 작은 값을 반환합니다. max(x1, x2, ..., xN)는 가장 큰 값을 반환합니다. 이 함수들의 정의역과 치역은 확장 수학적 값입니다.

표기 “x modulo y”(y유한이며 0이 아니어야 함)은 y와 부호가 같거나 0인 k 값을 계산하며, abs(k) < abs(y)이고, x - k = q × y정수 q가 존재합니다.

“the result of clamping x between lower and upper”(x확장 수학적 값, lower, upper수학적 값이고 lowerupper)은 x < lowerlower를, x > upperupper를, 그렇지 않으면 x를 반환합니다.

수학 함수 floor(x)x보다 크지 않은 가장 큰 정수(+∞에 가장 가까운)를 반환합니다.

참고

floor(x) = x - (x modulo 1).

수학 함수 truncate(x)x의 소수 부분을 제거하여 0에 가까워지도록 반올림합니다. x < 0이면 -floor(-x), 그렇지 않으면 floor(x)을 반환합니다.

수학 함수 min, max, abs, floor, truncate는 Number와 BigInt에는 정의되지 않으며, 비-수학적 값 인수가 사용되면 편집상 오류입니다.

구간(interval)은 하한 a에서 상한 b까지의, 같은 숫자 타입의 값을 요소로 가지는 (무한하거나 비어 있을 수 있는) 집합입니다. 각 경계는 포함 또는 배타로 설명됩니다. 다음 네 가지 구간이 있습니다:

  • 구간 a(포함)에서 b(포함)까지, 즉 포함 구간 a에서 b까지는 axb인 같은 타입의 값 x를 모두 포함합니다.
  • 구간 a(포함)에서 b(배타)까지는 ax < b인 값을 모두 포함합니다.
  • 구간 a(배타)에서 b(포함)까지는 a < xb인 값을 모두 포함합니다.
  • 구간 a(배타)에서 b(배타)까지는 a < x < b인 값을 모두 포함합니다.

예를 들어, 1(포함)에서 2(배타)까지의 구간은 1과 2 사이의 모든 수학적 값을 포함하며, 1은 포함하고 2는 포함하지 않습니다. 구간 정의를 위해 -0𝔽 < +0𝔽이므로, 예를 들어 하한이 +0𝔽포함 구간+0𝔽는 포함하지만 -0𝔽는 포함하지 않습니다. NaN은 어떤 구간에도 포함되지 않습니다.

5.2.6 값 표기법

이 명세에서 ECMAScript 언어 값굵은 글씨로 표시됩니다. 예시로 null, true, "hello" 등이 있습니다. 이는 ECMAScript 소스 텍스트(예: Function.prototype.apply 또는 let n = 42;)와 구별됩니다.

5.2.7 동일성(Identity)

이 명세에서는 명세 값과 ECMAScript 언어 값 모두 동등성 비교를 수행합니다. 비교 시 값은 두 범주로 나뉩니다. 동일성 없는 값(value without identity)은 모든 고유 특성이 같으면 서로 동등합니다— 예: 정수의 크기, 시퀀스의 길이 등. 동일성 없는 값은 특성을 완전히 기술하는 것만으로도 나타낼 수 있습니다. 반면, 동일성 있는 값(value with identity)은 고유하며 자기 자신과만 동등합니다. 동일성 있는 값은 동일성 없는 값과 같지만 identity라 불리는 추가적이고 유일하며 변하지 않는 특성을 가집니다. 기존 동일성 있는 값에 대한 참조는 단순히 특성을 기술하는 것만으로 생성할 수 없으며, 반드시 명시적으로 전달되어야 합니다. 동일성 있는 값 중 일부는 변경 가능(mutable)하며, 특성(동일성 제외)이 변경될 수 있어 모든 참조자에게 새로운 특성이 관찰됩니다. 동일성 없는 값은 동일성 있는 값과 절대 동등하지 않습니다.

명세 관점에서 “is”는 두 값을 동등성 비교하는 데 사용되며(예: “If bool is true, then ...”), “contains”는 리스트 내에서 동등성 비교로 값을 찾는 데 사용됩니다(예: "If list contains a Record r such that r.[[Foo]] is true, then ..."). 명세 동일성은 이러한 비교의 결과를 결정하며, 이 명세에서 공리적으로 정의됩니다.

ECMAScript 언어 관점에서는, 언어 값은 SameValue 추상 연산 및 그에 의해 전이적으로 호출되는 추상 연산으로 비교됩니다. 이 비교 추상 연산 알고리즘이 ECMAScript 언어 값언어 동일성을 결정합니다.

명세 값에 대해, 동일성 없는 값의 예는 수학적 값, 확장 수학적 값, ECMAScript 소스 텍스트, 서로게이트 페어, Directive Prologues 등, UTF-16 코드 유닛, Unicode 코드 포인트, enum, 추상 연산구문 지향 연산, host hook, 순서쌍 등입니다. 명세 동일성을 가지는 값의 예는 Record(Property Descriptor, PrivateElement 등 포함), 파싱 노드, List, SetRelation, Abstract Closure, Data Block, Private Name, 실행 컨텍스트, 실행 컨텍스트 스택, agent signifier, WaiterList Record 등입니다.

명세 동일성은 ECMAScript 언어 값Symbol.for로 생성된 Symbol 값을 제외하고는 모두 언어 동일성과 일치합니다. 명세 동일성도, 언어 동일성도 가지지 않는 ECMAScript 언어 값은 undefined, null, Boolean, String, Number, BigInt입니다. 명세 동일성과 언어 동일성을 모두 가지는 ECMAScript 언어 값은 Symbol(Symbol.for로 생성된 것은 제외)과 Object입니다. Symbol.for로 생성된 Symbol 값은 명세 동일성은 있으나 언어 동일성은 없습니다.

6 ECMAScript 데이터 타입과 값

이 명세의 알고리즘은 각 값이 관련 타입을 가진 값을 다룹니다. 가능한 값 타입은 바로 이 절에서 정의된 타입들입니다. 타입은 ECMAScript 언어 타입과 명세 타입으로 더 분류됩니다.

6.1 ECMAScript 언어 타입

ECMAScript 언어 타입은 ECMAScript 프로그래머가 ECMAScript 언어를 사용하여 직접 다루는 값에 해당합니다. ECMAScript 언어 타입에는 Undefined, Null, Boolean, String, Symbol, Number, BigInt, Object가 있습니다. ECMAScript 언어 값은 ECMAScript 언어 타입으로 특징지어지는 값입니다.

6.1.1 Undefined 타입

Undefined 타입은 undefined라 불리는 정확히 하나의 값을 가집니다. 값이 할당되지 않은 변수는 undefined 값을 가집니다.

6.1.2 Null 타입

Null 타입은 null이라 불리는 정확히 하나의 값을 가집니다.

6.1.3 Boolean 타입

Boolean 타입truefalse라 불리는 두 값을 가지는 논리적 개체를 나타냅니다.

6.1.4 String 타입

String 타입은 253 - 1개의 요소까지 0개 이상의 16비트 부호 없는 정수 값(“요소”)의 모든 순서 있는 시퀀스의 집합입니다. String 타입은 일반적으로 실행 중인 ECMAScript 프로그램에서 텍스트 데이터를 표현하는 데 사용되며, 이 경우 String의 각 요소는 UTF-16 코드 유닛 값으로 처리됩니다. 각 요소는 시퀀스 내에서 위치를 차지합니다. 이 위치는 0 이상의 정수로 인덱싱됩니다. 첫 번째 요소(있다면)는 인덱스 0에, 그 다음 요소는 인덱스 1에, 이런 식으로 이어집니다. String의 길이는 그 안의 요소(즉, 16비트 값) 개수입니다. 빈 문자열은 길이가 0이며 요소를 포함하지 않습니다.

String 내용을 해석하지 않는 ECMAScript 연산은 추가 의미를 적용하지 않습니다. String 값을 해석하는 연산은 각 요소를 하나의 UTF-16 코드 유닛으로 처리합니다. 하지만 ECMAScript는 이러한 코드 유닛의 값이나 관계를 제한하지 않으므로, String 내용을 UTF-16로 인코딩된 유니코드 코드 포인트 시퀀스로 추가 해석하는 연산은 잘못된 서브시퀀스를 고려해야 합니다. 그러한 연산은 다음 규칙에 따라 0xD800부터 0xDBFF까지의 포함 구간에 있는 코드 유닛(유니코드 표준에서 선행 서러게이트, 더 공식적으로는 고서러게이트 코드 유닛)과 0xDC00부터 0xDFFF까지의 포함 구간에 있는 코드 유닛(후행 서러게이트, 더 공식적으로는 저서러게이트 코드 유닛)을 특별히 처리합니다:

String.prototype.normalize 함수(22.1.3.15)는 String 값을 명시적으로 정규화하는 데 사용할 수 있습니다. String.prototype.localeCompare(22.1.3.12)는 내부적으로 String 값을 정규화하지만, 그 외 연산은 문자열을 암묵적으로 정규화하지 않습니다. 연산 결과는 달리 명시되지 않는 한, 언어 또는 로케일에 민감하지 않습니다.

참고

이 설계의 근거는 문자열 구현을 최대한 단순하고 빠르게 유지하기 위함이었습니다. ECMAScript 소스 텍스트가 정규형 C(Normalized Form C)라면, 문자열 리터럴도 유니코드 이스케이프 시퀀스를 포함하지 않는 한 정규화됨이 보장됩니다.

이 명세에서 “A, B, ...의 문자열 연결(string-concatenation)”(각 인자는 String 값, 코드 유닛, 코드 유닛 시퀀스임)은 각 인자의 코드 유닛(순서대로)을 이어붙인(순서대로) 코드 유닛 시퀀스로 구성된 String 값을 의미합니다.

SinclusiveStart에서 exclusiveEnd까지의 부분 문자열(substring)”(S는 String 값 또는 코드 유닛 시퀀스, inclusiveStartexclusiveEnd정수)는 S의 인덱스 inclusiveStart에서 시작해 exclusiveEnd 바로 앞까지의 연속된 코드 유닛으로 구성된 String 값을 의미합니다(만약 inclusiveStart = exclusiveEnd이면 빈 문자열). “to” 접미사가 생략되면 S의 길이가 exclusiveEnd 값으로 사용됩니다.

ASCII 단어 문자”는 다음 String 값을 의미합니다. 이 값은 유니코드 기본 라틴 블록 내의 모든 문자와 숫자 및 U+005F(LOW LINE)만으로 구성됩니다:
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_".
역사적 이유로 여러 알고리즘에서 의미가 있습니다.

6.1.4.1 StringIndexOf ( string, searchValue, fromIndex )

추상 연산 StringIndexOf는 string(String), searchValue(String), fromIndex(0 이상의 정수)를 인자로 받고, 0 이상의 정수 또는 not-found를 반환합니다. 다음 단계를 수행합니다:

  1. lenstring의 길이로 설정한다.
  2. searchValue가 빈 문자열이고 fromIndexlen이면 fromIndex를 반환한다.
  3. searchLensearchValue의 길이로 설정한다.
  4. fromIndexilen - searchLen인 모든 정수 i에 대해 오름차순으로 다음을 수행한다:
    1. candidatestringi에서 i + searchLen까지의 부분 문자열로 설정한다.
    2. candidatesearchValue와 같으면 i를 반환한다.
  5. not-found를 반환한다.
참고 1

searchValue가 빈 문자열이고 fromIndexstring의 길이인 경우, 이 알고리즘은 fromIndex를 반환합니다. 빈 문자열은 문자열 내의 모든 위치(마지막 코드 유닛 뒤까지 포함)에서 발견되는 것으로 간주됩니다.

참고 2

이 알고리즘은 fromIndex + searchValue의 길이가 string의 길이를 초과하면 항상 not-found를 반환합니다.

6.1.4.2 StringLastIndexOf ( string, searchValue, fromIndex )

추상 연산 StringLastIndexOf는 string(String), searchValue(String), fromIndex(0 이상의 정수)를 인자로 받고, 0 이상의 정수 또는 not-found를 반환합니다. 다음 단계를 수행합니다:

  1. lenstring의 길이로 설정한다.
  2. searchLensearchValue의 길이로 설정한다.
  3. Assert: fromIndex + searchLenlen.
  4. 0 ≤ ifromIndex인 모든 정수 i에 대해 내림차순으로 다음을 수행한다:
    1. candidatestringi에서 i + searchLen까지의 부분 문자열로 설정한다.
    2. candidatesearchValue와 같으면 i를 반환한다.
  5. not-found를 반환한다.
참고

searchValue가 빈 문자열인 경우, 이 알고리즘은 fromIndex를 반환합니다. 빈 문자열은 문자열 내의 모든 위치(마지막 코드 유닛 뒤까지 포함)에서 발견되는 것으로 간주됩니다.

6.1.5 심볼(Symbol) 타입

Symbol 타입은 객체 프로퍼티의 키로 사용할 수 있는 모든 문자열이 아닌 값의 집합입니다(6.1.7).

모든 Symbol 값은 고유하며 변경할 수 없습니다.

각 Symbol 값은 [[Description]]이라 불리는 관련 값을 변경 불가능하게 보유하며, 이는 undefined 또는 문자열 값입니다.

6.1.5.1 잘 알려진 심볼(Well-Known Symbols)

잘 알려진 심볼은 이 명세의 알고리즘에서 명시적으로 참조되는 내장 Symbol 값입니다. 일반적으로 명세 알고리즘의 확장 포인트로 사용되는 프로퍼티의 키로 사용됩니다. 별도 명시가 없는 한, 잘 알려진 심볼 값은 모든 realm(9.3)에서 공유됩니다.

이 명세에서는 잘 알려진 심볼을 표준 내장 표기법(intrinsic notation)을 사용하여 참조하며, 내장은 표 1에 나열된 값 중 하나입니다.

참고
이전 판 명세에서는 @@name 형태의 표기를 사용했으나, 현재 판에서는 %Symbol.name%를 사용합니다. 특히 다음 이름이 사용되었습니다: @@asyncIterator, @@hasInstance, @@isConcatSpreadable, @@iterator, @@match, @@matchAll, @@replace, @@search, @@species, @@split, @@toPrimitive, @@toStringTag, 그리고 @@unscopables.
표 1: 잘 알려진 심볼(Well-known Symbols)
명세 이름 [[Description]] 값 및 목적
%Symbol.asyncIterator% "Symbol.asyncIterator" 객체의 기본 비동기 이터레이터(async iterator)를 반환하는 메서드입니다. for-await-of 문의 의미론에서 호출됩니다.
%Symbol.hasInstance% "Symbol.hasInstance" 생성자(constructor) 객체가 특정 객체를 자신의 인스턴스로 인식하는지 결정하는 메서드입니다. instanceof 연산자의 의미론에서 호출됩니다.
%Symbol.isConcatSpreadable% "Symbol.isConcatSpreadable" true일 경우 Array.prototype.concat에 의해 객체가 배열 요소로 펼쳐져 평탄화(flatten)되어야 함을 나타내는 불리언 프로퍼티입니다.
%Symbol.iterator% "Symbol.iterator" 객체의 기본 이터레이터(iterator)를 반환하는 메서드입니다. for-of 문의 의미론에서 호출됩니다.
%Symbol.match% "Symbol.match" 정규식이 문자열과 매칭되는지 확인하는 정규식 메서드입니다. String.prototype.match 메서드에서 호출됩니다.
%Symbol.matchAll% "Symbol.matchAll" 정규식이 문자열 전체에서 매칭되는 부분을 이터레이터(iterator)로 반환하는 정규식 메서드입니다. String.prototype.matchAll 메서드에서 호출됩니다.
%Symbol.replace% "Symbol.replace" 문자열에서 매칭된 부분 문자열을 대체하는 정규식 메서드입니다. String.prototype.replace 메서드에서 호출됩니다.
%Symbol.search% "Symbol.search" 문자열 내에서 정규식이 매칭되는 인덱스를 반환하는 정규식 메서드입니다. String.prototype.search 메서드에서 호출됩니다.
%Symbol.species% "Symbol.species" 파생 객체를 생성하는 데 사용되는 생성자 함수인 함수 값 프로퍼티입니다.
%Symbol.split% "Symbol.split" 정규식과 매칭되는 인덱스에서 문자열을 분할하는 정규식 메서드입니다. String.prototype.split 메서드에서 호출됩니다.
%Symbol.toPrimitive% "Symbol.toPrimitive" 객체를 대응하는 원시값(primitive value)으로 변환하는 메서드입니다. ToPrimitive 추상 연산에서 호출됩니다.
%Symbol.toStringTag% "Symbol.toStringTag" 객체의 기본 문자열 설명을 생성할 때 사용하는 문자열 값 프로퍼티입니다. 내장 메서드 Object.prototype.toString에서 접근됩니다.
%Symbol.unscopables% "Symbol.unscopables" 자신의 프로퍼티 이름 및 상속된 프로퍼티 이름이 관련 객체의 with 환경 바인딩에서 제외되는 프로퍼티 이름인 객체 값 프로퍼티입니다.

6.1.6 숫자 타입

ECMAScript에는 두 가지 내장 숫자 타입이 있습니다: Number와 BigInt. 아래 추상 연산들은 이러한 숫자 타입에 대해 정의되어 있습니다. "결과" 열에는 반환 타입과, 일부 연산 호출 시 비정상 완료(abrupt completion)가 반환될 수 있는지 여부가 표시됩니다.

표 2: 숫자 타입 연산
연산(Operation) 예시 소스(Example source) Evaluation 의미론에서 호출됨 결과(Result)
Number::unaryMinus -x 단항 - 연산자 Number
BigInt::unaryMinus BigInt
Number::bitwiseNOT ~x 비트 NOT 연산자 (~) Number
BigInt::bitwiseNOT BigInt
Number::exponentiate x ** y 거듭제곱 연산자Math.pow ( base, exponent ) Number
BigInt::exponentiate BigInt를 포함하는 정상 완료(normal completion) 또는 예외 완료(throw completion)
Number::multiply x * y 곱셈 연산자(Multiplicative Operators) Number
BigInt::multiply BigInt
Number::divide x / y 곱셈 연산자(Multiplicative Operators) Number
BigInt::divide BigInt를 포함하는 정상 완료(normal completion) 또는 예외 완료(throw completion)
Number::remainder x % y 곱셈 연산자(Multiplicative Operators) Number
BigInt::remainder BigInt를 포함하는 정상 완료(normal completion) 또는 예외 완료(throw completion)
Number::add x ++
++ x
x + y
후위 증가 연산자(Postfix Increment Operator), 전위 증가 연산자(Prefix Increment Operator), 더하기 연산자(+) (The Addition Operator) Number
BigInt::add BigInt
Number::subtract x --
-- x
x - y
후위 감소 연산자(Postfix Decrement Operator), 전위 감소 연산자(Prefix Decrement Operator), 빼기 연산자(-) (The Subtraction Operator) Number
BigInt::subtract BigInt
Number::leftShift x << y 왼쪽 시프트 연산자(<<) (The Left Shift Operator) Number
BigInt::leftShift BigInt
Number::signedRightShift x >> y 부호 있는 오른쪽 시프트 연산자(>>) (The Signed Right Shift Operator) Number
BigInt::signedRightShift BigInt
Number::unsignedRightShift x >>> y 부호 없는 오른쪽 시프트 연산자(>>>) (The Unsigned Right Shift Operator) Number
BigInt::unsignedRightShift 예외 완료(throw completion)
Number::lessThan x < y
x > y
x <= y
x >= y
관계 연산자(Relational Operators), IsLessThan ( x, y, LeftFirst ) Boolean 또는 undefined (정렬되지 않은 입력)
BigInt::lessThan Boolean
Number::equal x == y
x != y
x === y
x !== y
동등 연산자(Equality Operators), IsStrictlyEqual ( x, y ) Boolean
BigInt::equal
Number::sameValue Object.is(x, y) 객체 내부 메서드, SameValue ( x, y )를 통해 정확한 값 비교 Boolean
Number::sameValueZero [x].includes(y) SameValueZero ( x, y )를 통해, +0𝔽-0𝔽의 차이를 무시하고 값 비교 (Array, Map, Set 메서드 등) Boolean
Number::bitwiseAND x & y 이진 비트 연산자(Binary Bitwise Operators) Number
BigInt::bitwiseAND BigInt
Number::bitwiseXOR x ^ y Number
BigInt::bitwiseXOR BigInt
Number::bitwiseOR x | y Number
BigInt::bitwiseOR BigInt
Number::toString String(x) 다양한 표현식 및 내장 함수에서, ToString ( argument )을 통해 호출됨 String
BigInt::toString

숫자 타입은 일반적으로 정밀도 손실이나 잘림(truncation) 없이 변환할 수 없기 때문에, ECMAScript 언어에서는 이러한 타입 간에 암묵적인 변환을 제공하지 않습니다. 프로그래머는 다른 타입을 요구하는 함수를 호출할 때 Number 또는 BigInt 함수를 명시적으로 호출하여 타입을 변환해야 합니다.

참고

ECMAScript의 초판 및 이후 판에서는 일부 연산자에 대해 정밀도 손실이나 잘림(truncate)이 발생할 수 있는 암묵적 숫자 변환을 제공했습니다. 이러한 레거시 암묵 변환은 하위 호환성을 위해 유지되지만, BigInt에는 제공되지 않습니다. 이는 프로그래머의 실수 가능성을 줄이고, 미래 판에서는 일반화된 값 타입(value types) 도입의 여지를 남기기 위함입니다.

6.1.6.1 Number 타입

Number 타입은 정확히 18,437,736,874,454,810,627개(즉, 264 - 253 + 3) 값을 가지며, IEEE 754-2019에서 지정된 IEEE 배정밀도 부동소수점(binary64) 값을 나타냅니다. 단, IEEE 표준의 9,007,199,254,740,990개(즉, 253 - 2) NaN 값은 ECMAScript에서는 하나의 특별한 NaN 값으로 표현됩니다. (NaN 값은 프로그램 표현식 NaN으로 생성됩니다.) 일부 구현에서는 외부 코드가 다양한 NaN 값을 구분할 수 있지만, 그러한 동작은 구현 정의(implementation-defined)입니다. ECMAScript 코드에서는 모든 NaN 값은 서로 구별되지 않습니다.

참고

Number 값이 ArrayBuffer(25.1)나 SharedArrayBuffer(25.2)에 저장된 후 관찰되는 비트 패턴은 ECMAScript 구현에서 사용하는 Number 값의 내부 표현과 반드시 같지 않을 수 있습니다.

그 외에도 양의 무한대(positive Infinity)음의 무한대(negative Infinity)라는 두 개의 특별한 값이 있습니다. 간결하게 각각 +∞𝔽-∞𝔽로도 설명합니다. (이 두 무한대 Number 값은 +Infinity(또는 Infinity)와 -Infinity 표현식으로 생성됩니다.)

나머지 18,437,736,874,454,810,624개(즉, 264 - 253) 값은 유한(finite) 숫자라 불립니다. 이 중 절반은 양수, 절반은 음수입니다. 모든 유한 양의 Number 값에는 동일한 크기의 음수 값이 대응됩니다.

양의 0(positive zero)와 음의 0(negative zero)도 있습니다. 간결하게 각각 +0𝔽-0𝔽로 설명합니다. (이 두 0 값은 +0(또는 0)과 -0 표현식으로 생성됩니다.)

18,437,736,874,454,810,622개(즉, 264 - 253 - 2) 유한 0이 아닌 값은 두 가지 종류가 있습니다:

18,428,729,675,200,069,632개(즉, 264 - 254)는 정규화(normalized)되어 있으며, 다음과 같은 형태를 가집니다:

s × m × 2e

여기서 s는 1 또는 -1, m정수이며 구간(interval) [252, 253)에 속하고, e정수이며 포함 구간 [-1074, 971]에 속합니다.

나머지 9,007,199,254,740,990개(즉, 253 - 2) 값은 비정규화(denormalized)되어 있으며, 다음과 같은 형태를 가집니다:

s × m × 2e

여기서 s는 1 또는 -1, m정수이며 구간(interval) (0, 252)에 속하고, e는 -1074입니다.

크기가 253 이하인 모든 양의 및 음의 정수는 Number 타입으로 표현 가능합니다. 정수 0은 Number 타입에서 +0𝔽-0𝔽 두 가지로 표현됩니다.

유한 숫자가 0이 아니고 위의 두 형태 중 정수 m이 홀수이면 홀수 시그니피컨드(odd significand)를 가지며, 그렇지 않으면 짝수 시그니피컨드(even significand)를 가집니다.

이 명세에서 “the Number value for x”라는 문구에서 x가 정확한 실수(π와 같은 무리수 포함)를 나타낼 때, 다음 방식으로 Number 값을 선택함을 의미합니다. Number 타입의 모든 유한 값 집합에서 -0𝔽을 제거하고, Number 타입으로 표현할 수 없는 두 값을 추가합니다: 21024(+1 × 253 × 2971)와 -21024(-1 × 253 × 2971). 이 집합에서 x에 가장 가까운 값을 선택합니다. 두 값이 동일하게 가까울 경우, 짝수 시그니피컨드를 가진 값을 선택합니다. 이때 두 추가 값 21024-21024은 짝수 시그니피컨드를 가진 것으로 간주합니다. 마지막으로, 21024가 선택되면 +∞𝔽로, -21024가 선택되면 -∞𝔽로, +0𝔽가 선택되면 x < 0일 때만 -0𝔽로 바꿉니다. 그 외의 경우 선택한 값을 그대로 사용합니다. 그 결과가 Number value for x입니다. (이 절차는 IEEE 754-2019의 roundTiesToEven 모드와 정확히 일치합니다.)

Number value for +∞는 +∞𝔽이고, Number value for -∞는 -∞𝔽입니다.

일부 ECMAScript 연산자는 정수의 특정 범위(예: 포함 구간 -231부터 231 - 1까지, 또는 포함 구간 0부터 216 - 1까지)만 다룹니다. 이러한 연산자는 Number 타입의 모든 값을 허용하지만, 우선 해당 값을 기대하는 범위의 정수 값으로 변환합니다. 숫자 변환 연산에 대한 설명은 7.1를 참조하세요.

6.1.6.1.1 Number::unaryMinus ( x )

추상 연산 Number::unaryMinus는 인자 x(Number)를 받고 Number를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. xNaN이면 NaN을 반환한다.
  2. x의 부호를 반전한 값을 반환한다. 즉, 크기는 같지만 부호가 반대인 Number를 계산한다.

6.1.6.1.2 Number::bitwiseNOT ( x )

추상 연산 Number::bitwiseNOT는 인자 x(Number)를 받고 정수(Number)를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. oldValue를 ! ToInt32(x)로 설정한다.
  2. oldValue의 비트 보수를 반환한다. 결과의 수학적 값은 32비트 2의 보수 비트열로 정확히 표현된다.

6.1.6.1.3 Number::exponentiate ( base, exponent )

추상 연산 Number::exponentiate는 인자 base(Number), exponent(Number)를 받고 Number를 반환합니다. baseexponent 거듭제곱한 결과를 나타내는 구현 근사값을 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. exponentNaN이면 NaN을 반환한다.
  2. exponent+0𝔽 또는 -0𝔽이면 1𝔽을 반환한다.
  3. baseNaN이면 NaN을 반환한다.
  4. base+∞𝔽이면
    1. exponent > +0𝔽이면 +∞𝔽을 반환하고, 아니면 +0𝔽을 반환한다.
  5. base-∞𝔽이면
    1. exponent > +0𝔽이면
      1. exponent가 홀수 정수(Number)이면 -∞𝔽을 반환, 아니면 +∞𝔽을 반환한다.
    2. 그 외
      1. exponent가 홀수 정수(Number)이면 -0𝔽을 반환, 아니면 +0𝔽을 반환한다.
  6. base+0𝔽이면
    1. exponent > +0𝔽이면 +0𝔽을 반환, 아니면 +∞𝔽을 반환한다.
  7. base-0𝔽이면
    1. exponent > +0𝔽이면
      1. exponent가 홀수 정수(Number)이면 -0𝔽을 반환, 아니면 +0𝔽을 반환한다.
    2. 그 외
      1. exponent가 홀수 정수(Number)이면 -∞𝔽을 반환, 아니면 +∞𝔽을 반환한다.
  8. Assert: base유한(finite)이며 +0𝔽 또는 -0𝔽이 아니다.
  9. exponent+∞𝔽이면
    1. abs((base)) > 1이면 +∞𝔽 반환
    2. abs((base)) = 1이면 NaN 반환
    3. abs((base)) < 1이면 +0𝔽 반환
  10. exponent-∞𝔽이면
    1. abs((base)) > 1이면 +0𝔽 반환
    2. abs((base)) = 1이면 NaN 반환
    3. abs((base)) < 1이면 +∞𝔽 반환
  11. Assert: exponent유한(finite)이며 +0𝔽 또는 -0𝔽이 아니다.
  12. base < -0𝔽이고 exponent정수(Number)가 아니면 NaN 반환
  13. 구현 근사값 Number 값을 반환하며, 이는 (base)를 (exponent) 거듭제곱한 값이다.
참고

base1𝔽 또는 -1𝔽이고 exponent+∞𝔽 또는 -∞𝔽인 경우, 또는 base1𝔽이고 exponentNaN인 경우의 base ** exponent 결과는 IEEE 754-2019와 다릅니다. ECMAScript 초판은 이 연산에서 NaN을 반환했지만, 이후 IEEE 754에서는 1𝔽을 명시합니다. 호환성 유지를 위해 ECMAScript의 역사적 동작을 따릅니다.

6.1.6.1.4 Number::multiply ( x, y )

추상 연산 Number::multiply는 인자 x(Number), y(Number)를 받고 Number를 반환합니다. IEEE 754-2019 배정밀도 이진 산술 규칙에 따라 곱셈을 수행하여 xy의 곱을 생성합니다. 호출 시 다음 단계를 수행합니다:

  1. xNaN이거나 yNaN이면 NaN 반환
  2. x+∞𝔽 또는 -∞𝔽이면
    1. y+0𝔽 또는 -0𝔽이면 NaN 반환
    2. y > +0𝔽이면 x 반환
    3. -x 반환
  3. y+∞𝔽 또는 -∞𝔽이면
    1. x+0𝔽 또는 -0𝔽이면 NaN 반환
    2. x > +0𝔽이면 y 반환
    3. -y 반환
  4. x-0𝔽이면
    1. y-0𝔽이거나 y < -0𝔽이면 +0𝔽 반환
    2. 그 외에는 -0𝔽 반환
  5. y-0𝔽이면
    1. x < -0𝔽이면 +0𝔽 반환
    2. 그 외에는 -0𝔽 반환
  6. 𝔽((x) × (y)) 반환
참고

유한(finite) 정밀 곱셈은 교환법칙은 성립하지만, 항상 결합법칙이 성립하는 것은 아닙니다.

6.1.6.1.5 Number::divide ( x, y )

추상 연산 Number::divide는 인자 x(Number), y(Number)를 받고 Number를 반환합니다. IEEE 754-2019 배정밀도 이진 산술 규칙에 따라 나눗셈을 수행하며, x를 피제수(dividend), y를 제수(divisor)로 하여 몫을 생성합니다. 호출 시 다음 단계를 수행합니다:

  1. xNaN이거나 yNaN이면 NaN 반환
  2. x+∞𝔽 또는 -∞𝔽이면
    1. y+∞𝔽 또는 -∞𝔽이면 NaN 반환
    2. y+0𝔽 또는 y > +0𝔽이면 x 반환
    3. -x 반환
  3. y+∞𝔽이면
    1. x+0𝔽 또는 x > +0𝔽이면 +0𝔽 반환, 아니면 -0𝔽 반환
  4. y-∞𝔽이면
    1. x+0𝔽 또는 x > +0𝔽이면 -0𝔽 반환, 아니면 +0𝔽 반환
  5. x+0𝔽 또는 -0𝔽이면
    1. y+0𝔽 또는 -0𝔽이면 NaN 반환
    2. y > +0𝔽이면 x 반환
    3. -x 반환
  6. y+0𝔽이면
    1. x > +0𝔽이면 +∞𝔽 반환, 아니면 -∞𝔽 반환
  7. y-0𝔽이면
    1. x > +0𝔽이면 -∞𝔽 반환, 아니면 +∞𝔽 반환
  8. 𝔽((x) / (y)) 반환

6.1.6.1.6 Number::remainder ( n, d )

추상 연산 Number::remainder는 인자 n(Number), d(Number)를 받고 Number를 반환합니다. n을 피제수(dividend), d를 제수(divisor)로 하는 암시적 나눗셈에서의 나머지를 구합니다. 호출 시 다음 단계를 수행합니다:

  1. nNaN이거나 dNaN이면 NaN을 반환한다.
  2. n+∞𝔽 또는 -∞𝔽이면 NaN을 반환한다.
  3. d+∞𝔽 또는 -∞𝔽이면 n을 반환한다.
  4. d+0𝔽 또는 -0𝔽이면 NaN을 반환한다.
  5. n+0𝔽 또는 -0𝔽이면 n을 반환한다.
  6. Assert: nd유한이며 0이 아니다.
  7. quotient(n) / (d)로 설정한다.
  8. qtruncate(quotient)로 설정한다.
  9. r(n) - ((d) × q)로 설정한다.
  10. r = 0이고 n < -0𝔽이면 -0𝔽을 반환한다.
  11. 𝔽(r)을 반환한다.
참고 1

C와 C++에서 나머지 연산자는 정수 피연산자만 허용하지만, ECMAScript에서는 부동소수점 피연산자도 허용합니다.

참고 2

% 연산자로 계산된 부동소수점 나머지 연산 결과는 IEEE 754-2019에서 정의한 "나머지(remainder)" 연산과 동일하지 않습니다. IEEE의 "remainder" 연산은 잘림이 아닌 반올림 나눗셈에서의 나머지를 계산하므로, 일반적인 정수 나머지 연산자와는 다릅니다. ECMAScript에서는 부동소수점 % 연산이 Java 정수 나머지 연산자와 유사하게 동작하도록 정의되어 있으며, 이는 C 표준 라이브러리의 fmod 함수와 비교할 수 있습니다.

6.1.6.1.7 Number::add ( x, y )

추상 연산 Number::add는 인자 x(Number), y(Number)를 받고 Number를 반환합니다. IEEE 754-2019 배정밀도 이진 산술 규칙에 따라 덧셈을 수행하여 인자의 합을 생성합니다. 호출 시 다음 단계를 수행합니다:

  1. xNaN이거나 yNaN이면 NaN 반환
  2. x+∞𝔽이고 y-∞𝔽이면 NaN 반환
  3. x-∞𝔽이고 y+∞𝔽이면 NaN 반환
  4. x+∞𝔽 또는 -∞𝔽이면 x 반환
  5. y+∞𝔽 또는 -∞𝔽이면 y 반환
  6. Assert: xy는 모두 유한이다.
  7. x-0𝔽이고 y-0𝔽이면 -0𝔽 반환
  8. 𝔽((x) + (y)) 반환
참고

유한 정밀 덧셈은 교환법칙은 성립하지만, 항상 결합법칙이 성립하는 것은 아닙니다.

6.1.6.1.8 Number::subtract ( x, y )

추상 연산 Number::subtract는 인자 x(Number), y(Number)를 받고 Number를 반환합니다. 뺄셈을 수행하여 피감수(minuend) x와 감수(subtrahend) y의 차를 생성합니다. 호출 시 다음 단계를 수행합니다:

  1. Number::add(x, Number::unaryMinus(y))를 반환한다.
참고

언제나 x - yx + (-y)와 동일한 결과를 생성합니다.

6.1.6.1.9 Number::leftShift ( x, y )

추상 연산 Number::leftShift는 인자 x(Number), y(Number)를 받고 정수(Number)를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. lNum을 ! ToInt32(x)로 설정한다.
  2. rNum을 ! ToUint32(y)로 설정한다.
  3. shiftCount(rNum) modulo 32로 설정한다.
  4. lNumshiftCount 비트만큼 왼쪽 시프트한 결과를 반환한다. 결과의 수학적 값은 32비트 2의 보수 비트열로 정확히 표현된다.

6.1.6.1.10 Number::signedRightShift ( x, y )

추상 연산 Number::signedRightShift는 인자 x(Number), y(Number)를 받고 정수(Number)를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. lNum을 ! ToInt32(x)로 설정한다.
  2. rNum을 ! ToUint32(y)로 설정한다.
  3. shiftCount(rNum) modulo 32로 설정한다.
  4. lNumshiftCount 비트만큼 부호 확장(right shift with sign extension) 하여 오른쪽 시프트한 결과를 반환한다. 최상위 비트가 전파된다. 결과의 수학적 값은 32비트 2의 보수 비트열로 정확히 표현된다.

6.1.6.1.11 Number::unsignedRightShift ( x, y )

추상 연산 Number::unsignedRightShift는 인자 x(Number), y(Number)를 받고 정수(Number)를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. lNum을 ! ToUint32(x)로 설정한다.
  2. rNum을 ! ToUint32(y)로 설정한다.
  3. shiftCount(rNum) modulo 32로 설정한다.
  4. lNumshiftCount 비트만큼 0으로 채우며 오른쪽 시프트한 결과를 반환한다. 비워진 비트는 0으로 채워진다. 결과의 수학적 값은 32비트 부호 없는 비트열로 정확히 표현된다.

6.1.6.1.12 Number::lessThan ( x, y )

추상 연산 Number::lessThan는 인자 x(Number), y(Number)를 받고 Boolean 또는 undefined를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. xNaN이면 undefined 반환
  2. yNaN이면 undefined 반환
  3. xy이면 false 반환
  4. x+0𝔽이고 y-0𝔽이면 false 반환
  5. x-0𝔽이고 y+0𝔽이면 false 반환
  6. x+∞𝔽이면 false 반환
  7. y+∞𝔽이면 true 반환
  8. y-∞𝔽이면 false 반환
  9. x-∞𝔽이면 true 반환
  10. Assert: xy유한이다.
  11. (x) < (y)이면 true 반환, 아니면 false 반환

6.1.6.1.13 Number::equal ( x, y )

추상 연산 Number::equal는 인자 x(Number), y(Number)를 받고 Boolean을 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. xNaN이면 false 반환
  2. yNaN이면 false 반환
  3. xy이면 true 반환
  4. x+0𝔽이고 y-0𝔽이면 true 반환
  5. x-0𝔽이고 y+0𝔽이면 true 반환
  6. false 반환

6.1.6.1.14 Number::sameValue ( x, y )

추상 연산 Number::sameValue는 인자 x(Number), y(Number)를 받고 Boolean을 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. xNaN이고 yNaN이면 true 반환
  2. x+0𝔽이고 y-0𝔽이면 false 반환
  3. x-0𝔽이고 y+0𝔽이면 false 반환
  4. xy이면 true 반환
  5. false 반환

6.1.6.1.15 Number::sameValueZero ( x, y )

추상 연산 Number::sameValueZero는 인자 x(Number), y(Number)를 받고 Boolean을 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. xNaN이고 yNaN이면 true 반환
  2. x+0𝔽이고 y-0𝔽이면 true 반환
  3. x-0𝔽이고 y+0𝔽이면 true 반환
  4. xy이면 true 반환
  5. false 반환

6.1.6.1.16 NumberBitwiseOp ( op, x, y )

추상 연산 NumberBitwiseOp는 인자 op(&, ^, 또는 |), x(Number), y(Number)를 받고 정수(Number)를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. lNum을 ! ToInt32(x)로 설정한다.
  2. rNum을 ! ToInt32(y)로 설정한다.
  3. lBits(lNum)을 나타내는 32비트 2의 보수 비트열로 설정한다.
  4. rBits(rNum)을 나타내는 32비트 2의 보수 비트열로 설정한다.
  5. op&이면
    1. resultlBitsrBits에 비트 AND 연산을 적용한 결과로 설정한다.
  6. 그 외 op^이면
    1. resultlBitsrBits에 비트 XOR 연산을 적용한 결과로 설정한다.
  7. 그 외
    1. Assert: op|이다.
    2. resultlBitsrBits에 비트 OR 연산을 적용한 결과로 설정한다.
  8. result 32비트 2의 보수 비트열이 나타내는 정수Number 값을 반환한다.

6.1.6.1.17 Number::bitwiseAND ( x, y )

추상 연산 Number::bitwiseAND는 인자 x(Number), y(Number)를 받고 정수(Number)를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. NumberBitwiseOp(&, x, y)를 반환한다.

6.1.6.1.18 Number::bitwiseXOR ( x, y )

추상 연산 Number::bitwiseXOR는 인자 x(Number), y(Number)를 받고 정수(Number)를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. NumberBitwiseOp(^, x, y)를 반환한다.

6.1.6.1.19 Number::bitwiseOR ( x, y )

추상 연산 Number::bitwiseOR는 인자 x(Number), y(Number)를 받고 정수(Number)를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. NumberBitwiseOp(|, x, y)를 반환한다.

6.1.6.1.20 Number::toString ( x, radix )

추상 연산 Number::toString은 인자 x(Number), radix(정수, 포함 구간 2~36)을 받고 String을 반환합니다. xradix 진법 위치 표기법(positional numeral system)으로 String으로 표현합니다. r 진법으로 수를 표현할 때 사용하는 숫자는 "0123456789abcdefghijklmnopqrstuvwxyz"의 앞 r 코드 유닛을 순서대로 사용합니다. 크기가 1𝔽 이상인 숫자의 표현에는 선행 0이 포함되지 않습니다. 호출 시 다음 단계를 수행합니다:

  1. xNaN이면 "NaN" 반환
  2. x+0𝔽 또는 -0𝔽이면 "0" 반환
  3. x < -0𝔽이면 string-concatenation("-", Number::toString(-x, radix)) 반환
  4. x+∞𝔽이면 "Infinity" 반환
  5. n, k, s정수로 정한다. k ≥ 1이며, radixk - 1s < radixk이고, 𝔽(s × radixn - k)가 x이며, k는 최소가 되도록 한다. ksradix로 표현할 때의 자릿수이며, sradix로 나누어떨어지지 않으며, 최하위 자릿수는 반드시 유일하게 결정되지는 않는다.
  6. radix ≠ 10 또는 n포함 구간 -5~21에 있으면
    1. nk이면
      1. sradix로 표현한 k자리 코드 유닛과, n - k개의 0x0030(DIGIT ZERO) 코드 유닛을 string-concatenation하여 반환한다.
    2. 그 외 n > 0이면
      1. sradix로 표현한 상위 n자리 코드 유닛, 0x002E(FULL STOP) 코드 유닛, 나머지 k - n자리 코드 유닛을 string-concatenation하여 반환한다.
    3. 그 외
      1. Assert: n ≤ 0.
      2. 0x0030(DIGIT ZERO), 0x002E(FULL STOP), -n개의 0x0030(DIGIT ZERO), sradix로 표현한 k자리 코드 유닛을 string-concatenation하여 반환한다.
  7. NOTE: 이 경우 입력은 1.2e+3과 같은 과학적 E 표기로 표현된다.
  8. Assert: radix는 10이다.
  9. n < 0이면
    1. exponentSign을 0x002D(HYPHEN-MINUS) 코드 유닛으로 설정한다.
  10. 그 외
    1. exponentSign을 0x002B(PLUS SIGN) 코드 유닛으로 설정한다.
  11. k = 1이면
    1. 단일 자리 s 코드 유닛, 0x0065(LATIN SMALL LETTER E), exponentSign, abs(n - 1)를 10진수로 표현한 코드 유닛을 string-concatenation하여 반환한다.
  12. 상위 자리 s의 10진수 코드 유닛, 0x002E(FULL STOP), 나머지 k - 1자리 10진수 코드 유닛, 0x0065(LATIN SMALL LETTER E), exponentSign, abs(n - 1)를 10진수로 표현한 코드 유닛을 string-concatenation하여 반환한다.
참고 1

다음 사항은 구현 가이드라인으로 유용할 수 있지만, 표준의 규범적 요구사항은 아닙니다:

  • x가 -0𝔽이 아닌 모든 Number 값이면, ToNumber(ToString(x))는 x와 같다.
  • s의 최하위 자릿수는 5 단계의 요구조건에 따라 항상 유일하게 결정되지 않는다.
참고 2

규칙보다 더 정확한 변환을 제공하는 구현에서는 아래 대체 버전의 5 단계를 가이드라인으로 사용하는 것이 권장됩니다:

  1. n, k, s정수로 정한다. k ≥ 1, radixk - 1s < radixk, 𝔽(s × radixn - k)가 x이며, k는 최소가 되도록 한다. s의 후보가 여러 개일 경우, s × radixn - k(x)에 가장 가까운 값을 s로 선택한다. 두 후보가 있을 경우 짝수 값을 선택한다. ksradix로 표현할 때의 자릿수이며, sradix로 나누어떨어지지 않는다.
참고 3

ECMAScript 구현자는 David M. Gay가 작성한 부동소수점 이진-10진 변환 관련 논문 및 코드를 참고할 수 있습니다:

Gay, David M. Correctly Rounded Binary-Decimal and Decimal-Binary Conversions. Numerical Analysis, Manuscript 90-10. AT&T Bell Laboratories (Murray Hill, New Jersey). 1990년 11월 30일.
https://ampl.com/_archive/first-website/REFS/rounding.pdf.
관련 코드: http://netlib.sandia.gov/fp/dtoa.c
http://netlib.sandia.gov/fp/g_fmt.c.
여러 netlib 미러 사이트에서도 찾을 수 있습니다.

6.1.6.2 BigInt 타입

BigInt 타입정수 값을 나타냅니다. 값의 크기는 제한이 없으며, 특정 비트 폭에 국한되지 않습니다. 별도 언급이 없는 한, 연산은 일반적으로 정확한 수학적 결과를 제공합니다. 이진 연산에서는 BigInt가 2의 보수 이진 문자열로 동작하며, 음수는 왼쪽으로 무한히 비트가 설정된 것으로 취급됩니다.

6.1.6.2.1 BigInt::unaryMinus ( x )

추상 연산 BigInt::unaryMinus는 인자 x(BigInt)를 받고 BigInt를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. x = 0이면 0를 반환한다.
  2. -x를 반환한다.

6.1.6.2.2 BigInt::bitwiseNOT ( x )

추상 연산 BigInt::bitwiseNOT는 인자 x(BigInt)를 받고 BigInt를 반환합니다. x의 1의 보수 값을 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. -x - 1를 반환한다.

6.1.6.2.3 BigInt::exponentiate ( base, exponent )

추상 연산 BigInt::exponentiate는 인자 base(BigInt), exponent(BigInt)를 받고 정상 완료 BigInt 또는 예외 완료를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. exponent < 0이면 RangeError 예외를 던진다.
  2. base = 0이고 exponent = 0이면 1를 반환한다.
  3. baseexponent 거듭제곱한 값을 반환한다.

6.1.6.2.4 BigInt::multiply ( x, y )

추상 연산 BigInt::multiply는 인자 x(BigInt), y(BigInt)를 받고 BigInt를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. x × y를 반환한다.
참고
결과가 입력보다 훨씬 더 큰 비트폭을 갖더라도 정확한 수학적 결과가 반환됩니다.

6.1.6.2.5 BigInt::divide ( x, y )

추상 연산 BigInt::divide는 인자 x(BigInt), y(BigInt)를 받고 정상 완료 BigInt 또는 예외 완료를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. y = 0이면 RangeError 예외를 던진다.
  2. quotient(x) / (y)로 설정한다.
  3. (truncate(quotient))를 반환한다.

6.1.6.2.6 BigInt::remainder ( n, d )

추상 연산 BigInt::remainder는 인자 n(BigInt), d(BigInt)를 받고 정상 완료 BigInt 또는 예외 완료를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. d = 0이면 RangeError 예외를 던진다.
  2. n = 0이면 0를 반환한다.
  3. quotient(n) / (d)로 설정한다.
  4. q(truncate(quotient))로 설정한다.
  5. n - (d × q)를 반환한다.
참고
결과의 부호는 피제수의 부호와 동일합니다.

6.1.6.2.7 BigInt::add ( x, y )

추상 연산 BigInt::add는 인자 x(BigInt), y(BigInt)를 받고 BigInt를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. x + y를 반환한다.

6.1.6.2.8 BigInt::subtract ( x, y )

추상 연산 BigInt::subtract는 인자 x(BigInt), y(BigInt)를 받고 BigInt를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. x - y를 반환한다.

6.1.6.2.9 BigInt::leftShift ( x, y )

추상 연산 BigInt::leftShift는 인자 x(BigInt), y(BigInt)를 받고 BigInt를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. y < 0이면
    1. (floor((x) / 2-(y)))를 반환한다.
  2. x × 2y를 반환한다.
참고
여기서 의미론은 BigInt를 무한 길이의 2의 보수 이진 문자열로 간주한 비트 시프트와 동일해야 합니다.

6.1.6.2.10 BigInt::signedRightShift ( x, y )

추상 연산 BigInt::signedRightShift는 인자 x(BigInt), y(BigInt)를 받고 BigInt를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. BigInt::leftShift(x, -y)를 반환한다.

6.1.6.2.11 BigInt::unsignedRightShift ( x, y )

추상 연산 BigInt::unsignedRightShift는 인자 x(BigInt), y(BigInt)를 받고 예외 완료를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. TypeError 예외를 던진다.

6.1.6.2.12 BigInt::lessThan ( x, y )

추상 연산 BigInt::lessThan는 인자 x(BigInt), y(BigInt)를 받고 Boolean을 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. (x) < (y)이면 true 반환, 아니면 false 반환

6.1.6.2.13 BigInt::equal ( x, y )

추상 연산 BigInt::equal는 인자 x(BigInt), y(BigInt)를 받고 Boolean을 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. (x) = (y)이면 true 반환, 아니면 false 반환

6.1.6.2.14 BinaryAnd ( x, y )

추상 연산 BinaryAnd는 인자 x(0 또는 1), y(0 또는 1)를 받고 0 또는 1을 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. x = 1이고 y = 1이면 1 반환
  2. 그 외에는 0 반환

6.1.6.2.15 BinaryOr ( x, y )

추상 연산 BinaryOr는 인자 x(0 또는 1), y(0 또는 1)를 받고 0 또는 1을 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. x = 1 또는 y = 1이면 1 반환
  2. 그 외에는 0 반환

6.1.6.2.16 BinaryXor ( x, y )

추상 연산 BinaryXor는 인자 x(0 또는 1), y(0 또는 1)를 받고 0 또는 1을 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. x = 1이고 y = 0이면 1 반환
  2. 그 외 x = 0이고 y = 1이면 1 반환
  3. 그 외에는 0 반환

6.1.6.2.17 BigIntBitwiseOp ( op, x, y )

추상 연산 BigIntBitwiseOp는 인자 op(&, ^, |), x(BigInt), y(BigInt)를 받고 BigInt를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. x(x)로 설정한다.
  2. y(y)로 설정한다.
  3. result를 0으로 설정한다.
  4. shift를 0으로 설정한다.
  5. 반복, (x = 0 또는 x = -1)이고 (y = 0 또는 y = -1)일 때까지
    1. xDigitx modulo 2로 설정한다.
    2. yDigity modulo 2로 설정한다.
    3. op&이면
      1. resultresult + 2shift × BinaryAnd(xDigit, yDigit)로 설정한다.
    4. 그 외 op|이면
      1. resultresult + 2shift × BinaryOr(xDigit, yDigit)로 설정한다.
    5. 그 외
      1. Assert: op^이다.
      2. resultresult + 2shift × BinaryXor(xDigit, yDigit)로 설정한다.
    6. shiftshift + 1로 설정한다.
    7. x를 (x - xDigit) / 2로 설정한다.
    8. y를 (y - yDigit) / 2로 설정한다.
  6. op&이면
    1. tmpBinaryAnd(x modulo 2, y modulo 2)로 설정한다.
  7. 그 외 op|이면
    1. tmpBinaryOr(x modulo 2, y modulo 2)로 설정한다.
  8. 그 외
    1. Assert: op^이다.
    2. tmpBinaryXor(x modulo 2, y modulo 2)로 설정한다.
  9. tmp ≠ 0이면
    1. resultresult - 2shift로 설정한다.
    2. 참고: 이 연산은 부호를 확장합니다.
  10. BigInt value for result를 반환한다.

6.1.6.2.18 BigInt::bitwiseAND ( x, y )

추상 연산 BigInt::bitwiseAND는 인자 x(BigInt), y(BigInt)를 받고 BigInt를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. BigIntBitwiseOp(&, x, y)를 반환한다.

6.1.6.2.19 BigInt::bitwiseXOR ( x, y )

추상 연산 BigInt::bitwiseXOR는 인자 x(BigInt), y(BigInt)를 받고 BigInt를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. BigIntBitwiseOp(^, x, y)를 반환한다.

6.1.6.2.20 BigInt::bitwiseOR ( x, y )

추상 연산 BigInt::bitwiseOR는 인자 x(BigInt), y(BigInt)를 받고 BigInt를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. BigIntBitwiseOp(|, x, y)를 반환한다.

6.1.6.2.21 BigInt::toString ( x, radix )

추상 연산 BigInt::toString은 인자 x(BigInt), radix(정수, 포함 구간 2~36)을 받고 String을 반환합니다. xradix 진법 위치 표기법으로 String으로 표현합니다. r 진법으로 BigInt를 표현할 때 사용하는 숫자는 "0123456789abcdefghijklmnopqrstuvwxyz"의 앞 r 코드 유닛을 순서대로 사용합니다. 0이 아닌 BigInt의 표현에는 결코 선행 0이 포함되지 않습니다. 호출 시 다음 단계를 수행합니다:

  1. x < 0이면 string-concatenation("-", BigInt::toString(-x, radix))를 반환한다.
  2. xradix로 표현한 String 값을 반환한다.

6.1.7 오브젝트 타입

Object 타입 인스턴스(간단히 “오브젝트”라 부름)는 프로퍼티의 집합을 나타냅니다. 각 프로퍼티는 데이터 프로퍼티 또는 접근자 프로퍼티입니다:

  • 데이터 프로퍼티는 키 값을 ECMAScript 언어 값과 Boolean 속성 집합에 연결합니다.
  • 접근자 프로퍼티는 키 값을 하나 또는 두 개의 접근자 함수와 Boolean 속성 집합에 연결합니다. 접근자 함수는 해당 프로퍼티에 연결된 ECMAScript 언어 값를 저장하거나 검색하는 데 사용됩니다.

오브젝트의 프로퍼티는 프로퍼티 키를 사용하여 고유하게 식별됩니다. 프로퍼티 키는 문자열(String) 또는 심볼(Symbol)입니다. 빈 문자열을 포함한 모든 문자열과 심볼은 프로퍼티 키로 사용할 수 있습니다. 프로퍼티 이름프로퍼티 키문자열(String)인 값입니다.

정수 인덱스프로퍼티 이름 n으로, CanonicalNumericIndexString(n)이 정수(Number)포함 구간 +0𝔽 ~ 𝔽(253 - 1) 내에서 반환하는 경우를 의미합니다. 배열 인덱스정수 인덱스 n으로, CanonicalNumericIndexString(n)이 정수(Number)포함 구간 +0𝔽 ~ 𝔽(232 - 2) 내에서 반환하는 경우를 의미합니다.

참고

모든 음이 아닌 안전 정수는 해당하는 정수 인덱스가 있습니다. 32비트 부호 없는 정수232 - 1을 제외한 모든 값은 해당하는 배열 인덱스가 있습니다. "-0"정수 인덱스배열 인덱스에 해당하지 않습니다.

프로퍼티 키는 프로퍼티 및 그 값을 접근하는 데 사용됩니다. 프로퍼티 접근 방법에는 get(값 조회)과 set(값 할당)의 두 가지가 있습니다. get/set 접근으로 접근 가능한 프로퍼티에는 오브젝트의 자신의 프로퍼티(own properties)와, 프로퍼티 상속 관계를 통해 다른 연관 객체가 제공하는 상속 프로퍼티(inherited properties)가 포함됩니다. 상속 프로퍼티는 연관 객체의 own이나 inherited 프로퍼티일 수 있습니다. 한 오브젝트의 모든 own 프로퍼티는 서로 다른 키 값을 가져야 합니다.

모든 오브젝트는 논리적으로 프로퍼티의 집합이지만, 프로퍼티 접근 및 조작의 의미론에 따라 여러 형태의 오브젝트가 존재합니다. 다양한 오브젝트 형태에 대한 정의는 6.1.7.2를 참고하세요.

또한 일부 오브젝트는 호출할 수 있습니다. 이들은 함수 또는 함수 오브젝트라 부르며, 아래에서 더 자세히 설명합니다. ECMAScript의 모든 함수는 Object 타입의 멤버입니다.

6.1.7.1 프로퍼티 속성

속성은 이 명세에서 표 3에 설명된 대로 객체 프로퍼티의 상태를 정의하고 설명하는 데 사용됩니다. 명시적으로 지정하지 않는 한, 각 속성의 초기값은 기본값(Default Value)입니다.

표 3: 객체 프로퍼티의 속성
속성 이름 해당 프로퍼티 타입 값의 도메인 기본값 설명
[[Value]] 데이터 프로퍼티 ECMAScript 언어 값 undefined get 접근 시 프로퍼티에서 조회되는 값입니다.
[[Writable]] 데이터 프로퍼티 Boolean false false일 경우, ECMAScript 코드에서 [[Set]]으로 [[Value]] 속성을 변경하려 해도 성공하지 않습니다.
[[Get]] 접근자 프로퍼티 오브젝트 또는 undefined undefined 값이 오브젝트라면, 반드시 함수 오브젝트여야 합니다. 함수의 [[Call]] 내부 메서드(표 5)가 빈 인자 리스트로 호출되어, get 접근 시마다 프로퍼티 값을 반환합니다.
[[Set]] 접근자 프로퍼티 오브젝트 또는 undefined undefined 값이 오브젝트라면, 반드시 함수 오브젝트여야 합니다. 함수의 [[Call]] 내부 메서드(표 5)가 단일 인자로 할당값을 넘겨 호출되며, set 접근 시마다 실행됩니다. 프로퍼티의 [[Set]] 내부 메서드의 효과는, 이후 [[Get]] 내부 메서드 호출 결과에 영향을 줄 수도 있고, 주지 않을 수도 있습니다.
[[Enumerable]] 데이터 프로퍼티 또는 접근자 프로퍼티 Boolean false true이면, for-in 반복문(14.7.5)에 의해 열거됩니다. 그렇지 않으면, 해당 프로퍼티는 비열거형(non-enumerable)입니다.
[[Configurable]] 데이터 프로퍼티 또는 접근자 프로퍼티 Boolean false false인 경우, 해당 프로퍼티를 삭제하거나, 데이터 프로퍼티접근자 프로퍼티로, 또는 반대로 변경하거나, (기존 [[Value]] 교체나 [[Writable]]false로 변경하는 경우를 제외하고) 속성에 변경을 가하려 해도 실패합니다.

6.1.7.2 오브젝트 내부 메서드와 내부 슬롯

ECMAScript에서 오브젝트의 실제 의미론은 내부 메서드라 불리는 알고리즘으로 지정됩니다. ECMAScript 엔진의 각 오브젝트는 런타임 동작을 정의하는 일련의 내부 메서드와 연관되어 있습니다. 이러한 내부 메서드는 ECMAScript 언어의 일부가 아니며, 명세상 설명 목적으로만 정의됩니다. 하지만 ECMAScript 구현 내의 각 오브젝트는 해당 내부 메서드가 명세한 대로 동작해야 합니다. 그 구현 방식은 구현체에 따라 다릅니다.

내부 메서드 이름은 다형적입니다. 즉, 동일한 내부 메서드 이름이 호출될 때 오브젝트 값에 따라 서로 다른 알고리즘이 실행될 수 있습니다. 내부 메서드가 호출되는 실제 오브젝트가 "타겟"입니다. 런타임 시 어떤 알고리즘이 오브젝트가 지원하지 않는 내부 메서드를 사용하려고 하면 TypeError 예외가 발생합니다.

내부 슬롯은 오브젝트와 연관된 내부 상태를 나타내며, 다양한 ECMAScript 명세 알고리즘에서 사용됩니다. 내부 슬롯은 오브젝트 프로퍼티가 아니며 상속되지도 않습니다. 내부 슬롯 명세에 따라 해당 상태는 ECMAScript 언어 타입 또는 명세 타입 값일 수 있습니다. 별도 명시가 없는 한, 내부 슬롯은 오브젝트 생성 과정에서 할당되며, 동적으로 추가될 수 없습니다. 별도 명시가 없는 한, 내부 슬롯의 초기값은 undefined입니다. 명세의 다양한 알고리즘은 내부 슬롯이 있는 오브젝트를 생성합니다. 하지만 ECMAScript 언어 자체에서는 오브젝트에 내부 슬롯을 직접 연결할 방법이 없습니다.

모든 오브젝트는 [[PrivateElements]]라는 내부 슬롯을 갖는데, 이는 List 타입의 PrivateElements 목록입니다. 이 List는 해당 오브젝트의 private 필드, 메서드, 접근자의 값을 나타냅니다. 초기값은 빈 List입니다.

내부 메서드와 내부 슬롯은 명세에서 [[ ]]로 감싸서 표기됩니다.

표 4는 ECMAScript 코드로 생성하거나 조작할 수 있는 모든 오브젝트에 적용되는 필수 내부 메서드를 요약합니다. 모든 오브젝트는 이 필수 내부 메서드의 알고리즘을 가져야 합니다. 그러나 모든 오브젝트가 반드시 동일한 알고리즘을 사용하는 것은 아닙니다.

일반 오브젝트는 다음 조건을 모두 만족하는 오브젝트입니다:

  • 표 4에 나열된 내부 메서드에 대해, 10.1에 정의된 메서드를 사용한다.
  • 오브젝트에 [[Call]] 내부 메서드가 있으면, 10.2.1 또는 10.3.1 중 하나를 사용한다.
  • 오브젝트에 [[Construct]] 내부 메서드가 있으면, 10.2.2 또는 10.3.2 중 하나를 사용한다.

이색 오브젝트(exotic object)일반 오브젝트가 아닌 오브젝트입니다.

이 명세는 오브젝트의 내부 메서드에 따라 다양한 이색 오브젝트 유형을 구분합니다. 어떤 오브젝트가 특정 종류의 이색 오브젝트(예: 배열 이색 오브젝트 또는 바운드 함수 이색 오브젝트 등)와 동작상 동일하더라도 명세된 내부 메서드 모음을 모두 갖추지 않으면 그 종류로 인식되지 않습니다.

표 4의 “시그니처(Signature)” 열 및 유사한 표들은 각 내부 메서드의 호출 패턴을 설명합니다. 호출 패턴에는 항상 괄호로 감싼 설명적 인자 이름들이 포함됩니다. 인자 이름이 ECMAScript 타입명과 같으면 해당 타입이어야 함을 의미합니다. 내부 메서드가 명시적으로 반환값을 가지면 인자 목록 뒤에 “→”와 반환 타입이 붙습니다. 이 시그니처에 쓰인 타입 이름은 6절 정의에 다음 명칭이 추가된 것입니다. “any”는 ECMAScript 언어 타입 중 아무 값이나 올 수 있음을 의미합니다.

내부 메서드는 인자 외에도 항상 호출 타겟 오브젝트에 접근할 수 있습니다.

내부 메서드는 암시적으로 Completion Record를 반환합니다. 이는 normal completion(호출 패턴에서 제시된 반환 타입 값을 감쌈) 또는 throw completion일 수 있습니다.

표 4: 필수 내부 메서드
내부 메서드 시그니처 설명
[[GetPrototypeOf]] ( ) Object | Null 이 오브젝트의 상속 프로퍼티를 제공하는 오브젝트를 결정합니다. null은 상속 프로퍼티가 없음을 의미합니다.
[[SetPrototypeOf]] (Object | Null) Boolean 이 오브젝트를 상속 프로퍼티를 제공하는 다른 오브젝트와 연결합니다. null을 넘기면 상속 프로퍼티가 없음을 의미합니다. 연산이 성공하면 true, 실패하면 false를 반환합니다.
[[IsExtensible]] ( ) Boolean 이 오브젝트에 추가 프로퍼티를 추가할 수 있는지 여부를 결정합니다.
[[PreventExtensions]] ( ) Boolean 이 오브젝트에 새 프로퍼티를 추가할 수 있는지 제어합니다. 연산이 성공하면 true, 실패하면 false를 반환합니다.
[[GetOwnProperty]] (propertyKey) Undefined | Property Descriptor 이 오브젝트의 own 프로퍼티 중 propertyKey를 키로 하는 프로퍼티에 대한 Property Descriptor를 반환하거나, 해당 프로퍼티가 없으면 undefined를 반환합니다.
[[DefineOwnProperty]] (propertyKey, PropertyDescriptor) Boolean propertyKey를 키로 하는 own 프로퍼티를 PropertyDescriptor로 기술된 상태로 생성하거나 변경합니다. 성공하면 true, 아니면 false를 반환합니다.
[[HasProperty]] (propertyKey) Boolean 이 오브젝트에 propertyKey를 키로 하는 own 또는 상속 프로퍼티가 있는지 Boolean 값으로 반환합니다.
[[Get]] (propertyKey, Receiver) any 이 오브젝트에서 propertyKey를 키로 하는 프로퍼티의 값을 반환합니다. 프로퍼티 값을 얻기 위해 ECMAScript 코드를 실행해야 하는 경우, Receiver가 코드 평가 시 this 값으로 사용됩니다.
[[Set]] (propertyKey, value, Receiver) Boolean propertyKey에 해당하는 프로퍼티의 값을 value로 설정합니다. 프로퍼티 값을 설정하기 위해 ECMAScript 코드를 실행해야 하는 경우, Receiver가 코드 평가 시 this 값으로 사용됩니다. 설정에 성공하면 true, 실패하면 false를 반환합니다.
[[Delete]] (propertyKey) Boolean 이 오브젝트에서 propertyKey를 키로 하는 own 프로퍼티를 삭제합니다. 프로퍼티가 삭제되지 않고 여전히 존재하면 false를 반환합니다. 프로퍼티가 삭제됐거나 존재하지 않으면 true를 반환합니다.
[[OwnPropertyKeys]] ( ) List of property keys 이 오브젝트의 own 프로퍼티 키 전체를 요소로 갖는 List를 반환합니다.

표 5는 함수로 호출 가능한 오브젝트가 지원하는 추가 필수 내부 메서드를 요약합니다. 함수 오브젝트[[Call]] 내부 메서드를 지원하는 오브젝트이고, 생성자[[Construct]] 내부 메서드를 지원하는 오브젝트입니다. [[Construct]]를 지원하는 모든 오브젝트는 반드시 [[Call]]도 지원해야 합니다. 즉, 모든 생성자함수 오브젝트여야 합니다. 따라서 생성자생성자 함수 또는 생성자 함수 오브젝트라고도 부를 수 있습니다.

표 5: 함수 오브젝트의 추가 필수 내부 메서드
내부 메서드 시그니처 설명
[[Call]] (any, List of any) any 이 오브젝트와 연관된 코드를 실행합니다. 함수 호출 표현식으로 호출됩니다. 내부 메서드의 인자는 this 값과, 호출 표현식으로 함수에 전달된 인자를 요소로 갖는 List입니다. 이 내부 메서드를 구현한 오브젝트는 호출 가능(callable)합니다.
[[Construct]] (List of any, Object) Object 오브젝트를 생성합니다. new 연산자나 super 호출을 통해 실행됩니다. 내부 메서드의 첫 번째 인자는 List로, 생성자 호출 또는 super 호출의 인자들을 요소로 갖습니다. 두 번째 인자는 new 연산자가 처음 적용된 오브젝트입니다. 이 내부 메서드를 구현한 오브젝트를 생성자라 합니다. 함수 오브젝트가 반드시 생성자인 것은 아니며, [[Construct]] 내부 메서드가 없는 함수 오브젝트도 있습니다.

일반 오브젝트와 표준 이색 오브젝트의 필수 내부 메서드의 의미론은 10절에 명시되어 있습니다. 만약 이색 오브젝트의 내부 메서드를 구현에서 지원하지 않는 경우, 해당 사용 시 TypeError 예외를 반드시 발생시켜야 합니다.

6.1.7.3 필수 내부 메서드의 불변 조건

ECMAScript 엔진의 오브젝트 내부 메서드는 아래에 명시된 불변 조건(invariant)을 반드시 준수해야 합니다. 이 명세의 일반 ECMAScript 오브젝트 및 모든 표준 이색 오브젝트는 이러한 불변 조건을 유지합니다. ECMAScript Proxy 오브젝트는 [[ProxyHandler]] 오브젝트의 트랩(trap) 결과에 대한 런타임 검사를 통해 이 불변 조건을 유지합니다.

구현체가 제공하는 이색 오브젝트도 반드시 이 불변 조건을 지켜야 합니다. 이러한 불변 조건이 위반되면 ECMAScript 코드에서 예측 불가한 동작이나 보안 문제가 발생할 수 있습니다. 단, 이 불변 조건 위반이 구현체의 메모리 안전성을 절대 해쳐서는 안 됩니다.

구현체는 필수 내부 메서드의 기능을 우회적으로 제공하여 이 불변 조건을 우회할 수 있게 해서는 안 됩니다.

정의(Definitions):

  • 내부 메서드의 target은 해당 내부 메서드가 호출되는 오브젝트입니다.
  • [[IsExtensible]] 내부 메서드가 false를 반환하거나, [[PreventExtensions]] 내부 메서드가 true를 반환한 경우 그 타겟은 비확장(non-extensible)입니다.
  • 존재하지 않는(non-existent) 프로퍼티란 비확장 타겟에 own 프로퍼티로 존재하지 않는 프로퍼티입니다.
  • SameValue에 대한 참조는 SameValue 알고리즘의 정의에 따릅니다.

반환 값(Return value):

모든 내부 메서드의 반환 값은 다음 중 하나를 가지는 Completion Record여야 합니다:

  • [[Type]] = normal, [[Target]] = empty, [[Value]] = 해당 내부 메서드의 아래에 명시된 "정상 반환 타입(normal return type)"의 값
  • [[Type]] = throw, [[Target]] = empty, [[Value]] = 임의의 ECMAScript 언어 값
참고 1

내부 메서드는 continue completion, break completion, return completion을 반환해서는 안 됩니다.

[[GetPrototypeOf]] ( )

  • 정상 반환 타입은 Object 또는 Null입니다.
  • 타겟이 비확장이고 [[GetPrototypeOf]]가 값 V를 반환한 경우, 이후 모든 [[GetPrototypeOf]] 호출은 SameValueV와 동일한 값을 반환해야 합니다.
참고 2

오브젝트의 프로토타입 체인은 유한 길이를 가져야 합니다(즉, 어떤 오브젝트에서 시작해 [[GetPrototypeOf]] 내부 메서드를 재귀적으로 적용하면 결국 null에 도달해야 함). 하지만 프로토타입 체인에 일반 오브젝트의 정의를 따르지 않는 이색 오브젝트가 포함되면 이 조건은 오브젝트 수준에서 강제할 수 없습니다. 이러한 순환 프로토타입 체인은 오브젝트 프로퍼티 접근 시 무한 루프를 야기할 수 있습니다.

[[SetPrototypeOf]] ( V )

  • 정상 반환 타입은 Boolean입니다.
  • 타겟이 비확장일 때, V가 타겟의 관찰된 [[GetPrototypeOf]] 값과 SameValue가 아닌 한 [[SetPrototypeOf]]는 반드시 false를 반환해야 합니다.

[[IsExtensible]] ( )

  • 정상 반환 타입은 Boolean입니다.
  • [[IsExtensible]]false를 반환한 경우, 이후 해당 타겟의 모든 [[IsExtensible]] 호출은 false를 반환해야 합니다.

[[PreventExtensions]] ( )

  • 정상 반환 타입은 Boolean입니다.
  • [[PreventExtensions]]true를 반환한 경우, 이후 해당 타겟의 모든 [[IsExtensible]] 호출은 false를 반환해야 하며, 타겟은 이제 비확장으로 간주합니다.

[[GetOwnProperty]] ( P )

  • 정상 반환 타입은 Property Descriptor 또는 Undefined입니다.
  • 반환값이 Property Descriptor이면, 반드시 모든 필드가 채워진 Property Descriptor여야 합니다.
  • P가 비설정 가능/비쓰기 가능 own 데이터 프로퍼티로 기술된 경우, 이후의 모든 [[GetOwnProperty]] ( P ) 호출은 [[Value]]P[[Value]]SameValueProperty Descriptor를 반환해야 합니다.
  • P[[Writable]][[Value]] 이외의 속성이 변할 수 있거나, 프로퍼티가 삭제될 수 있다면 P[[Configurable]] 속성은 true여야 합니다.
  • [[Writable]] 속성이 false에서 true로 바뀔 수 있다면, [[Configurable]] 속성도 true여야 합니다.
  • 타겟이 비확장이고 P가 존재하지 않는 own 프로퍼티라면, 이후의 모든 [[GetOwnProperty]] (P) 호출은 P를 존재하지 않는 것으로 설명해야 하며, 즉 [[GetOwnProperty]] (P)는 undefined를 반환해야 합니다.
참고 3

세 번째 불변 조건의 결과로, 어떤 프로퍼티가 데이터 프로퍼티로 기술되고 시간이 지남에 따라 다른 값을 반환할 수 있는 경우, 해당 프로퍼티의 [[Writable]]이나 [[Configurable]] 속성, 또는 둘 다 true여야 합니다. 비록 그 값을 바꿀 수 있는 메커니즘이 다른 필수 내부 메서드로 노출되어 있지 않더라도 말입니다.

[[DefineOwnProperty]] ( P, Desc )

  • 정상 반환 타입은 Boolean입니다.
  • [[DefineOwnProperty]]P가 타겟의 비설정 가능 own 프로퍼티로 관찰된 적이 있다면, 아래 둘 중 하나가 아닌 한 반드시 false를 반환해야 합니다:
    1. P가 쓰기 가능한 데이터 프로퍼티이다. 비설정 가능 쓰기 가능한 데이터 프로퍼티는 비설정 가능 비쓰기 가능한 데이터 프로퍼티로 변경될 수 있다.
    2. Desc의 모든 속성이 P의 속성과 SameValue이다.
  • [[DefineOwnProperty]] (P, Desc)는 타겟이 비확장이면서 P가 존재하지 않는 own 프로퍼티라면 반드시 false를 반환해야 합니다. 즉, 비확장 타겟 오브젝트에는 새 프로퍼티를 추가할 수 없습니다.

[[HasProperty]] ( P )

  • 정상 반환 타입은 Boolean입니다.
  • P가 타겟의 비설정 가능 own 데이터 또는 접근자 프로퍼티로 관찰된 적이 있다면, [[HasProperty]]true를 반환해야 합니다.

[[Get]] ( P, Receiver )

  • 정상 반환 타입은 ECMAScript 언어 타입 중 임의의 값입니다.
  • P가 값 V를 가진 비설정 가능/비쓰기 가능 own 데이터 프로퍼티로 관찰된 적이 있다면, [[Get]]은 반드시 VSameValue인 값을 반환해야 합니다.
  • P[[Get]] 속성이 undefined인 비설정 가능 own 접근자 프로퍼티로 관찰된 적이 있다면, [[Get]] 연산은 반드시 undefined를 반환해야 합니다.

[[Set]] ( P, V, Receiver )

  • 정상 반환 타입은 Boolean입니다.
  • P가 비설정 가능/비쓰기 가능 own 데이터 프로퍼티로 관찰된 적이 있다면, [[Set]]VP[[Value]]SameValue인 경우를 제외하고 반드시 false를 반환해야 합니다.
  • P[[Set]] 속성이 undefined인 비설정 가능 own 접근자 프로퍼티로 관찰된 적이 있다면, [[Set]] 연산은 반드시 false를 반환해야 합니다.

[[Delete]] ( P )

  • 정상 반환 타입은 Boolean입니다.
  • P가 타겟의 비설정 가능 own 데이터 또는 접근자 프로퍼티로 관찰된 적이 있다면, [[Delete]]false를 반환해야 합니다.

[[OwnPropertyKeys]] ( )

  • 정상 반환 타입은 List입니다.
  • 반환된 List에는 중복 항목이 없어야 합니다.
  • 반환된 List의 각 요소는 프로퍼티 키여야 합니다.
  • 반환된 List에는 이전에 관찰된 모든 비설정 가능 own 프로퍼티의 키가 반드시 포함되어야 합니다.
  • 타겟이 비확장일 경우, 반환된 List에는 [[GetOwnProperty]]로 관찰 가능한 타겟의 모든 own 프로퍼티의 키만 포함되어야 합니다.

[[Call]] ( )

[[Construct]] ( )

  • 정상 반환 타입은 Object입니다.
  • 타겟은 [[Call]] 내부 메서드도 반드시 가지고 있어야 합니다.

6.1.7.4 잘 알려진 내장 객체

잘 알려진 내장 객체들은 이 명세의 알고리즘에 의해 명시적으로 참조되는 내장 객체들이며, 일반적으로 realm별로 고유한 정체성을 가진다. 별도로 명시되지 않는 한, 각 내장 객체는 실제로는 각 realm마다 유사한 객체 집합에 해당한다.

이 명세에서 %name%과 같은 참조는 현재 realm에 연결된, 해당 name에 해당하는 내장 객체를 의미한다. %name.a.b%와 같은 참조는, ECMAScript 코드가 평가되기 전에 내장 객체 %name%의 "a" 속성의 값에서 "b" 속성을 접근한 것과 같다. 현재 realm과 그 내장 객체들의 결정 방법은 9.4에 설명되어 있다. 잘 알려진 내장 객체들의 목록은 표 6에 나와 있다.

표 6: 잘 알려진 내장 객체
내장 이름 전역 이름 ECMAScript 언어 연관성
%AggregateError% AggregateError AggregateError 생성자 (20.5.7.1)
%Array% Array Array 생성자 (23.1.1)
%ArrayBuffer% ArrayBuffer ArrayBuffer 생성자 (25.1.4)
%ArrayIteratorPrototype% Array Iterator 객체의 프로토타입 (23.1.5)
%AsyncFromSyncIteratorPrototype% Async-from-Sync Iterator 객체의 프로토타입 (27.1.6)
%AsyncFunction% async 함수 객체생성자 (27.7.1)
%AsyncGeneratorFunction% async generator 함수 객체생성자 (27.4.1)
%AsyncGeneratorPrototype% async generator 객체의 프로토타입 (27.6)
%AsyncIteratorPrototype% 모든 표준 내장 async iterator 객체가 간접적으로 상속하는 객체
%Atomics% Atomics Atomics 객체 (25.4)
%BigInt% BigInt BigInt 생성자 (21.2.1)
%BigInt64Array% BigInt64Array BigInt64Array 생성자 (23.2)
%BigUint64Array% BigUint64Array BigUint64Array 생성자 (23.2)
%Boolean% Boolean Boolean 생성자 (20.3.1)
%DataView% DataView DataView 생성자 (25.3.2)
%Date% Date Date 생성자 (21.4.2)
%decodeURI% decodeURI decodeURI 함수 (19.2.6.1)
%decodeURIComponent% decodeURIComponent decodeURIComponent 함수 (19.2.6.2)
%encodeURI% encodeURI encodeURI 함수 (19.2.6.3)
%encodeURIComponent% encodeURIComponent encodeURIComponent 함수 (19.2.6.4)
%Error% Error Error 생성자 (20.5.1)
%eval% eval eval 함수 (19.2.1)
%EvalError% EvalError EvalError 생성자 (20.5.5.1)
%FinalizationRegistry% FinalizationRegistry FinalizationRegistry 생성자 (26.2.1)
%Float16Array% Float16Array Float16Array 생성자 (23.2)
%Float32Array% Float32Array Float32Array 생성자 (23.2)
%Float64Array% Float64Array Float64Array 생성자 (23.2)
%ForInIteratorPrototype% For-In Iterator 객체의 프로토타입 (14.7.5.10)
%Function% Function Function 생성자 (20.2.1)
%GeneratorFunction% generator 함수 객체생성자 (27.3.1)
%GeneratorPrototype% generator 객체의 프로토타입 (27.5)
%Int8Array% Int8Array Int8Array 생성자 (23.2)
%Int16Array% Int16Array Int16Array 생성자 (23.2)
%Int32Array% Int32Array Int32Array 생성자 (23.2)
%isFinite% isFinite isFinite 함수 (19.2.2)
%isNaN% isNaN isNaN 함수 (19.2.3)
%Iterator% Iterator Iterator 생성자 (27.1.3.1)
%IteratorHelperPrototype% Iterator Helper 객체의 프로토타입 (27.1.2.1)
%JSON% JSON JSON 객체 (25.5)
%Map% Map Map 생성자 (24.1.1)
%MapIteratorPrototype% Map Iterator 객체의 프로토타입 (24.1.5)
%Math% Math Math 객체 (21.3)
%Number% Number Number 생성자 (21.1.1)
%Object% Object Object 생성자 (20.1.1)
%parseFloat% parseFloat parseFloat 함수 (19.2.4)
%parseInt% parseInt parseInt 함수 (19.2.5)
%Promise% Promise Promise 생성자 (27.2.3)
%Proxy% Proxy Proxy 생성자 (28.2.1)
%RangeError% RangeError RangeError 생성자 (20.5.5.2)
%ReferenceError% ReferenceError ReferenceError 생성자 (20.5.5.3)
%Reflect% Reflect Reflect 객체 (28.1)
%RegExp% RegExp RegExp 생성자 (22.2.4)
%RegExpStringIteratorPrototype% RegExp String Iterator 객체의 프로토타입 (22.2.9)
%Set% Set Set 생성자 (24.2.2)
%SetIteratorPrototype% Set Iterator 객체의 프로토타입 (24.2.6)
%SharedArrayBuffer% SharedArrayBuffer SharedArrayBuffer 생성자 (25.2.3)
%String% String String 생성자 (22.1.1)
%StringIteratorPrototype% String Iterator 객체의 프로토타입 (22.1.5)
%Symbol% Symbol Symbol 생성자 (20.4.1)
%SyntaxError% SyntaxError SyntaxError 생성자 (20.5.5.4)
%ThrowTypeError% 함수 객체로, 무조건 %TypeError%의 새 인스턴스를 throw함
%TypedArray% 모든 typed Array 생성자의 슈퍼 클래스 (23.2.1)
%TypeError% TypeError TypeError 생성자 (20.5.5.5)
%Uint8Array% Uint8Array Uint8Array 생성자 (23.2)
%Uint8ClampedArray% Uint8ClampedArray Uint8ClampedArray 생성자 (23.2)
%Uint16Array% Uint16Array Uint16Array 생성자 (23.2)
%Uint32Array% Uint32Array Uint32Array 생성자 (23.2)
%URIError% URIError URIError 생성자 (20.5.5.6)
%WeakMap% WeakMap WeakMap 생성자 (24.3.1)
%WeakRef% WeakRef WeakRef 생성자 (26.1.1)
%WeakSet% WeakSet WeakSet 생성자 (24.4.1)
%WrapForValidIteratorPrototype% Iterator.from에서 반환되는 래핑된 iterator 객체의 프로토타입 (27.1.3.2.1.1)
참고

표 102에 추가 항목이 있습니다.

6.2 ECMAScript 명세 타입

명세 타입은 ECMAScript 언어 구성 요소와 ECMAScript 언어 타입의 의미를 설명하기 위해 알고리즘 내에서 사용되는 메타값에 해당한다. 명세 타입에는 Reference Record, List, Completion Record, Property Descriptor, Environment Record, Abstract Closure, 그리고 Data Block이 포함된다. 명세 타입 값은 명세상의 산출물로, ECMAScript 구현 내의 특정 엔티티에 반드시 대응하지는 않는다. 명세 타입 값은 ECMAScript 표현식 평가의 중간 결과를 설명하는 데 사용될 수 있지만, 이러한 값은 객체의 프로퍼티나 ECMAScript 언어 변수의 값으로 저장될 수 없다.

6.2.1 Enum 명세 타입

Enums는 명세 내부에서만 사용되는 값으로, ECMAScript 코드에서는 직접적으로 관찰할 수 없다. Enum은 sans-serif 글꼴로 표기된다. 예를 들어, Completion Record[[Type]] 필드는 normal, return, 또는 throw와 같은 값을 가진다. Enum은 이름 외의 특징이 없다. Enum의 이름은 단지 다른 Enum과 구분하기 위한 용도일 뿐이며, 사용법이나 문맥상의 의미를 암시하지 않는다.

6.2.2 List와 Record 명세 타입

List 타입은 new 표현식의 인수 리스트 평가( 13.3.8 참고), 함수 호출, 기타 값의 간단한 순서형 리스트가 필요한 알고리즘의 설명에 사용된다. List 타입의 값은 개별 값으로 구성된 리스트 요소들의 단순한 순서 시퀀스이다. 이 시퀀스의 길이는 임의일 수 있다. 리스트의 요소는 0부터 시작하는 인덱스로 임의 접근이 가능하다. 표기상의 편의를 위해 배열과 유사한 문법으로 List 요소에 접근할 수 있다. 예를 들어, arguments[2]는 List arguments의 세 번째 요소를 의미한다.

알고리즘이 List의 요소를 순서 지정 없이 반복할 때, 사용되는 순서는 List의 요소 순서이다.

이 명세 내에서 표기상의 편의를 위해, 리터럴 문법으로 새 List 값을 표현할 수 있다. 예를 들어, « 1, 2 »는 두 개의 요소를 가지며 각각 특정 값으로 초기화된 List 값을 정의한다. 새로운 빈 List는 « »로 표현할 수 있다.

이 명세에서 "the list-concatenation of A, B, ..." (각 인수가 비어 있을 수도 있는 List임)은 각 인수의 요소(순서대로)를 연결한 새로운 List 값을 의미한다.

List of String에 대해 "sorted according to lexicographic code unit order"라는 문구는, 짧은 문자열의 길이만큼 각 코드 유닛의 숫자값으로 정렬하고, 모두 같으면 짧은 문자열을 긴 문자열보다 먼저 정렬함을 의미한다. 이는 IsLessThan 추상 연산에서 설명된다.

Record 타입은 이 명세의 알고리즘 내에서 데이터 집합을 설명하는 데 사용된다. Record 타입 값은 하나 이상의 이름 붙은 필드로 구성된다. 각 필드의 값은 ECMAScript 언어 값 또는 명세 값이다. 필드 이름은 항상 이중 대괄호로 감싸며, 예를 들어 [[Value]]와 같다.

이 명세 내에서 표기상의 편의를 위해, 객체 리터럴과 유사한 문법으로 Record 값을 표현할 수 있다. 예를 들어, { [[Field1]]: 42, [[Field2]]: false, [[Field3]]: empty }는 세 개의 필드를 각각 특정 값으로 초기화한 Record 값을 정의한다. 필드 이름의 순서는 중요하지 않다. 명시적으로 나열되지 않은 필드는 존재하지 않는 것으로 간주한다.

명세 텍스트와 알고리즘에서는 점 표기법을 사용해 Record 값의 특정 필드를 참조할 수 있다. 예를 들어, 위에서 보인 record R에 대해 R.[[Field2]]는 “R의 [[Field2]]라는 이름의 필드”를 의미한다.

자주 사용되는 Record 필드 조합의 스키마는 이름을 붙일 수 있으며, 그 이름을 리터럴 Record 값에 접두사로 사용하여 특정 집합의 종류를 명확히 할 수 있다. 예: PropertyDescriptor { [[Value]]: 42, [[Writable]]: false, [[Configurable]]: true }.

6.2.3 Set과 Relation 명세 타입

Set 타입은 메모리 모델에서 사용하기 위한 비순서 요소의 집합을 설명하는 데 사용된다. ECMAScript의 같은 이름을 가진 컬렉션 타입과는 다르다. 혼동을 피하기 위해, 이 명세에서는 ECMAScript 컬렉션의 인스턴스를 항상 "Set 객체"라고 부른다. Set 타입의 값은 중복 없는 단순한 요소 집합이며, 요소를 추가하거나 제거할 수 있다. Set끼리는 합집합, 교집합, 차집합 연산이 가능하다.

Relation 타입은 Set에 대한 제약 조건을 설명하는 데 사용된다. Relation 타입의 값은 값 도메인에서의 순서쌍의 Set이다. 예를 들어, 이벤트에 대한 Relation은 이벤트 순서쌍의 집합이다. Relation RR의 값 도메인에 속한 두 값 ab에 대해, a R b는 순서쌍 (a, b)가 R의 멤버임을 의미하는 약칭이다. Relation이 어떤 조건에 대해 최소 Relation일 때, 이는 그 조건을 만족하는 가장 작은 Relation임을 의미한다.

strict partial order는 Relation 값 R이 다음 조건을 만족할 때를 말한다.

  • 모든 a, b, cR의 도메인에 있을 때:

    • a R a가 아니다.
    • a R b이고 b R c이면, a R c이다.
참고 1

위 두 속성은 각각 반사성 없음(irreflexivity)과 추이성(transitivity)이라 한다.

strict total order는 Relation 값 R이 다음 조건을 만족할 때를 말한다.

  • 모든 a, b, cR의 도메인에 있을 때:

    • ab와 같거나 a R b이거나 b R a이다.
    • a R a가 아니다.
    • a R b이고 b R c이면, a R c이다.
참고 2

위 세 속성은 각각 전체성(totality), 반사성 없음(irreflexivity), 추이성(transitivity)이라 한다.

6.2.4 완료 레코드 명세 타입

완료 레코드 명세 타입은 값의 런타임 전파와 break, continue, return, throw와 같이 비지역적 제어 흐름 전이를 수행하는 구문의 동작과 같은 제어 흐름을 설명하는 데 사용된다.

완료 레코드는 표 7에 정의된 필드를 가진다.

표 7: 완료 레코드 필드
필드 이름 의미
[[Type]] normal, break, continue, return, 또는 throw 발생한 완료의 타입.
[[Value]] 완료 레코드가 아닌 임의의 값 생성된 값.
[[Target]] 문자열 또는 empty 지정된 제어 전이의 대상 레이블.

다음과 같은 축약 용어가 때때로 완료 레코드를 지칭하는 데 사용된다.

  • 정상 완료[[Type]] 값이 normal인 모든 완료 레코드를 의미한다.
  • break 완료[[Type]] 값이 break인 모든 완료 레코드를 의미한다.
  • continue 완료[[Type]] 값이 continue인 모든 완료 레코드를 의미한다.
  • return 완료[[Type]] 값이 return인 모든 완료 레코드를 의미한다.
  • throw 완료[[Type]] 값이 throw인 모든 완료 레코드를 의미한다.
  • 비정상 완료[[Type]] 값이 normal이 아닌 모든 완료 레코드를 의미한다.
  • 특정 값이 포함된 정상 완료[[Value]] 필드에 해당 타입의 값을 가진 정상 완료를 의미한다.

이 명세에서 정의된 호출 가능한 객체는 정상 완료 또는 throw 완료만 반환해야 한다. 그 외의 완료 레코드를 반환하는 것은 편집상의 오류로 간주된다.

구현 정의 호출 가능한 객체는 정상 완료 또는 throw 완료만 반환해야 한다.

6.2.4.1 NormalCompletion ( value )

추상 연산 NormalCompletion은 value (완료 레코드가 아닌 임의의 값)를 인수로 받아 정상 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. 완료 레코드 { [[Type]]: normal, [[Value]]: value, [[Target]]: empty }를 반환한다.

6.2.4.2 ThrowCompletion ( value )

추상 연산 ThrowCompletion은 value (ECMAScript 언어 값)를 인수로 받아 throw 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. 완료 레코드 { [[Type]]: throw, [[Value]]: value, [[Target]]: empty }를 반환한다.

6.2.4.3 ReturnCompletion ( value )

추상 연산 ReturnCompletion은 value (ECMAScript 언어 값)를 인수로 받아 return 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. 완료 레코드 { [[Type]]: return, [[Value]]: value, [[Target]]: empty }를 반환한다.

6.2.4.4 UpdateEmpty ( completionRecord, value )

추상 연산 UpdateEmpty는 completionRecord ( 완료 레코드 )와 value ( 완료 레코드가 아닌 임의의 값 )를 인수로 받아 완료 레코드를 반환한다. 호출 시 다음 단계를 수행한다:

  1. Assert: completionRecordreturn 완료 또는 throw 완료인 경우, completionRecord.[[Value]]empty가 아니어야 한다.
  2. 만약 completionRecord.[[Value]]empty가 아니라면, ? completionRecord를 반환한다.
  3. 완료 레코드 { [[Type]]: completionRecord.[[Type]], [[Value]]: value, [[Target]]: completionRecord.[[Target]] }를 반환한다.

6.2.5 Reference Record 명세 타입

Reference Record 타입은 delete, typeof, 대입 연산자, super 키워드 및 기타 언어 기능의 동작을 설명하는 데 사용된다. 예를 들어, 대입의 왼쪽 피연산자는 Reference Record를 생성해야 한다.

Reference Record는 해석된 이름 또는 (아직 해석되지 않았을 수도 있는) 프로퍼티 바인딩이며, 그 필드는 표 8에 정의되어 있다.

표 8: Reference Record 필드
필드 이름 의미
[[Base]] ECMAScript 언어 값 또는 Environment Record 혹은 unresolvable 바인딩을 보유하는 값 또는 Environment Record. [[Base]]unresolvable이면 바인딩을 해결할 수 없음을 나타낸다.
[[ReferencedName]] ECMAScript 언어 값 또는 Private Name 바인딩의 이름. [[Base]] 값이 Environment Record일 때는 항상 문자열이다. 그렇지 않으면, 문자열이나 심볼이 아닌 ECMAScript 언어 값일 수 있으며, ToPropertyKey가 수행될 때까지 유지된다.
[[Strict]] Boolean true이면 Reference Recordstrict mode 코드에서 생성된 것이고, false이면 그렇지 않다.
[[ThisValue]] ECMAScript 언어 값 또는 empty empty가 아닌 경우, 해당 Reference Recordsuper 키워드를 사용하여 표현된 프로퍼티 바인딩을 나타내며, 이를 Super Reference Record라 한다. 이 경우 [[Base]] 값은 Environment Record가 될 수 없다. 이때 [[ThisValue]] 필드는 this 값(Reference Record가 생성될 당시의 값)을 보유한다.

Reference Record를 다루기 위해 이 명세에서 다음 추상 연산들이 사용된다:

6.2.5.1 IsPropertyReference ( V )

추상 연산 IsPropertyReference는 인수 V ( Reference Record )를 받아 Boolean을 반환한다. 호출 시 다음 단계를 수행한다:

  1. V.[[Base]]unresolvable이면 false를 반환한다.
  2. V.[[Base]]Environment Record이면 false를, 아니면 true를 반환한다.

6.2.5.2 IsUnresolvableReference ( V )

추상 연산 IsUnresolvableReference는 인수 V ( Reference Record )를 받아 Boolean을 반환한다. 호출 시 다음 단계를 수행한다:

  1. V.[[Base]]unresolvable이면 true를, 아니면 false를 반환한다.

6.2.5.3 IsSuperReference ( V )

추상 연산 IsSuperReference는 인수 V ( Reference Record )를 받아 Boolean을 반환한다. 호출 시 다음 단계를 수행한다:

  1. V.[[ThisValue]]empty가 아니면 true를, 아니면 false를 반환한다.

6.2.5.4 IsPrivateReference ( V )

추상 연산 IsPrivateReference는 인수 V ( Reference Record )를 받아 Boolean을 반환한다. 호출 시 다음 단계를 수행한다:

  1. V.[[ReferencedName]]Private Name이면 true를, 아니면 false를 반환한다.

6.2.5.5 GetValue ( V )

추상 연산 GetValue는 인수 V ( Reference Record 또는 ECMAScript 언어 값 )를 받아 특정 값을 포함하는 정상 완료 ECMAScript 언어 값 또는 비정상 완료 중 하나를 반환한다. 호출 시 다음 단계를 수행한다:

  1. VReference Record가 아니면 V를 반환한다.
  2. IsUnresolvableReference(V) 가 true이면 ReferenceError 예외를 throw한다.
  3. IsPropertyReference(V) 가 true이면, 다음을 수행한다:
    1. baseObj를 ? ToObject(V.[[Base]])로 설정한다.
    2. IsPrivateReference(V) 가 true이면, 다음을 수행한다:
      1. PrivateGet(baseObj, V.[[ReferencedName]])를 반환한다.
    3. V.[[ReferencedName]]property key가 아니면, 다음을 수행한다:
      1. V.[[ReferencedName]]을 ? ToPropertyKey(V.[[ReferencedName]])로 설정한다.
    4. baseObj.[[Get]](V.[[ReferencedName]], GetThisValue(V))를 반환한다.
  4. 그 외의 경우,
    1. baseV.[[Base]]로 설정한다.
    2. Assert: baseEnvironment Record여야 한다.
    3. base.GetBindingValue(V.[[ReferencedName]], V.[[Strict]])를 반환한다 (9.1 참고).
참고

3.a 단계에서 생성될 수 있는 객체는 위 추상 연산과 ordinary object[[Get]] 내부 메서드 외부에서는 접근할 수 없다. 구현체는 실제 객체 생성을 생략할 수 있다.

6.2.5.6 PutValue ( V, W )

추상 연산 PutValue는 인수 V ( Reference Record 또는 ECMAScript 언어 값 )와 W ( ECMAScript 언어 값 )를 받아, 특정 값을 포함하는 정상 완료 unused 또는 비정상 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. VReference Record가 아니면 ReferenceError 예외를 throw한다.
  2. IsUnresolvableReference(V) 가 true이면, 다음을 수행한다:
    1. V.[[Strict]]true이면 ReferenceError 예외를 throw한다.
    2. globalObjGetGlobalObject()로 설정한다.
    3. Set(globalObj, V.[[ReferencedName]], W, false)를 수행한다.
    4. unused를 반환한다.
  3. IsPropertyReference(V) 가 true이면, 다음을 수행한다:
    1. baseObj를 ? ToObject(V.[[Base]])로 설정한다.
    2. IsPrivateReference(V) 가 true이면, 다음을 수행한다:
      1. PrivateSet(baseObj, V.[[ReferencedName]], W)를 반환한다.
    3. V.[[ReferencedName]]property key가 아니면, 다음을 수행한다:
      1. V.[[ReferencedName]]을 ? ToPropertyKey(V.[[ReferencedName]])로 설정한다.
    4. succeeded를 ? baseObj.[[Set]](V.[[ReferencedName]], W, GetThisValue(V))로 설정한다.
    5. succeededfalse이고 V.[[Strict]]true이면 TypeError 예외를 throw한다.
    6. unused를 반환한다.
  4. 그 외의 경우,
    1. baseV.[[Base]]로 설정한다.
    2. Assert: baseEnvironment Record여야 한다.
    3. base.SetMutableBinding(V.[[ReferencedName]], W, V.[[Strict]])를 반환한다 (9.1 참고).
참고

3.a 단계에서 생성될 수 있는 객체는 위 추상 연산과 ordinary object[[Set]] 내부 메서드 외부에서는 접근할 수 없다. 구현체는 실제 객체 생성을 생략할 수 있다.

6.2.5.7 GetThisValue ( V )

추상 연산 GetThisValue는 인수 V ( Reference Record )를 받아 ECMAScript 언어 값을 반환한다. 호출 시 다음 단계를 수행한다:

  1. Assert: IsPropertyReference(V) 가 true임을 보장한다.
  2. IsSuperReference(V) 가 true이면 V.[[ThisValue]]를, 아니면 V.[[Base]]를 반환한다.

6.2.5.8 InitializeReferencedBinding ( V, W )

추상 연산 InitializeReferencedBinding은 인수 V ( Reference Record )와 W ( ECMAScript 언어 값 )를 받아, 특정 값을 포함하는 정상 완료 unused 또는 비정상 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. Assert: IsUnresolvableReference(V) 가 false임을 보장한다.
  2. baseV.[[Base]]로 설정한다.
  3. Assert: baseEnvironment Record여야 한다.
  4. base.InitializeBinding(V.[[ReferencedName]], W)를 반환한다.

6.2.5.9 MakePrivateReference ( baseValue, privateIdentifier )

추상 연산 MakePrivateReference는 인수 baseValue ( ECMAScript 언어 값 )와 privateIdentifier (문자열)을 받아 Reference Record를 반환한다. 호출 시 다음 단계를 수행한다:

  1. privateEnv실행 중인 실행 컨텍스트의 PrivateEnvironment로 설정한다.
  2. Assert: privateEnvnull이 아님을 보장한다.
  3. privateNameResolvePrivateIdentifier(privateEnv, privateIdentifier)로 설정한다.
  4. 다음과 같은 Reference Record를 반환한다: { [[Base]]: baseValue, [[ReferencedName]]: privateName, [[Strict]]: true, [[ThisValue]]: empty }.

6.2.6 프로퍼티 디스크립터 명세 타입

Property Descriptor 타입은 객체 프로퍼티 속성의 조작 및 구체화(reification)를 설명하는 데 사용된다. Property Descriptor는 0개 이상의 필드를 가진 Record이며, 각 필드의 이름은 속성 이름이고 값은 6.1.7.1에 명시된 해당 속성 값이다. 이 명세 내에서 리터럴 Property Descriptor 레코드의 태그로 사용되는 스키마 이름은 “PropertyDescriptor”이다.

Property Descriptor 값은 특정 필드의 존재 또는 사용에 따라 데이터 프로퍼티 디스크립터와 접근자 프로퍼티 디스크립터로 더 분류될 수 있다. 데이터 프로퍼티 디스크립터는 [[Value]] 또는 [[Writable]]라는 이름의 필드가 포함된 것이다. 접근자 프로퍼티 디스크립터는 [[Get]] 또는 [[Set]]라는 이름의 필드가 포함된 것이다. 어떤 Property Descriptor도 [[Enumerable]][[Configurable]]라는 이름의 필드를 가질 수 있다. Property Descriptor 값은 데이터 프로퍼티 디스크립터이면서 접근자 프로퍼티 디스크립터일 수는 없지만, 둘 다 아닐 수는 있다(이 경우 일반 프로퍼티 디스크립터이다). 완전히 채워진 Property Descriptor는 접근자 프로퍼티 디스크립터 또는 데이터 프로퍼티 디스크립터 중 하나이면서 표 3에 명시된 모든 해당 필드를 가진 것이다.

Property Descriptor 값을 다루기 위해 이 명세에서는 다음 추상 연산들이 사용된다:

6.2.6.1 IsAccessorDescriptor ( Desc )

추상 연산 IsAccessorDescriptor는 인수 Desc ( Property Descriptor )를 받아 Boolean을 반환한다. 호출 시 다음 단계를 수행한다:

  1. Desc[[Get]] 필드가 있으면 true를 반환한다.
  2. Desc[[Set]] 필드가 있으면 true를 반환한다.
  3. false를 반환한다.

6.2.6.2 IsDataDescriptor ( Desc )

추상 연산 IsDataDescriptor는 인수 Desc ( Property Descriptor )를 받아 Boolean을 반환한다. 호출 시 다음 단계를 수행한다:

  1. Desc[[Value]] 필드가 있으면 true를 반환한다.
  2. Desc[[Writable]] 필드가 있으면 true를 반환한다.
  3. false를 반환한다.

6.2.6.3 IsGenericDescriptor ( Desc )

추상 연산 IsGenericDescriptor는 인수 Desc ( Property Descriptor )를 받아 Boolean을 반환한다. 호출 시 다음 단계를 수행한다:

  1. IsAccessorDescriptor(Desc) 가 true이면 false를 반환한다.
  2. IsDataDescriptor(Desc) 가 true이면 false를 반환한다.
  3. true를 반환한다.

6.2.6.4 FromPropertyDescriptor ( Desc )

추상 연산 FromPropertyDescriptor는 인수 Desc ( Property Descriptor 또는 undefined )를 받아 객체 또는 undefined를 반환한다. 호출 시 다음 단계를 수행한다:

  1. Descundefined이면 undefined를 반환한다.
  2. objOrdinaryObjectCreate(%Object.prototype%)로 설정한다.
  3. Assert: obj는 자체 프로퍼티가 없는 확장 가능한 ordinary object여야 한다.
  4. Desc[[Value]] 필드가 있으면, 다음을 수행한다:
    1. CreateDataPropertyOrThrow(obj, "value", Desc.[[Value]])를 수행한다.
  5. Desc[[Writable]] 필드가 있으면, 다음을 수행한다:
    1. CreateDataPropertyOrThrow(obj, "writable", Desc.[[Writable]])를 수행한다.
  6. Desc[[Get]] 필드가 있으면, 다음을 수행한다:
    1. CreateDataPropertyOrThrow(obj, "get", Desc.[[Get]])를 수행한다.
  7. Desc[[Set]] 필드가 있으면, 다음을 수행한다:
    1. CreateDataPropertyOrThrow(obj, "set", Desc.[[Set]])를 수행한다.
  8. Desc[[Enumerable]] 필드가 있으면, 다음을 수행한다:
    1. CreateDataPropertyOrThrow(obj, "enumerable", Desc.[[Enumerable]])를 수행한다.
  9. Desc[[Configurable]] 필드가 있으면, 다음을 수행한다:
    1. CreateDataPropertyOrThrow(obj, "configurable", Desc.[[Configurable]])를 수행한다.
  10. obj를 반환한다.

6.2.6.5 ToPropertyDescriptor ( Obj )

추상 연산 ToPropertyDescriptor는 인수 Obj ( ECMAScript 언어 값 )를 받아, 특정 값을 포함하는 정상 완료 Property Descriptor 또는 throw 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. Obj객체가 아니면, TypeError 예외를 throw한다.
  2. desc를 처음에는 필드가 없는 새로운 Property Descriptor로 설정한다.
  3. hasEnumerable을 ? HasProperty(Obj, "enumerable")로 설정한다.
  4. hasEnumerabletrue이면, 다음을 수행한다:
    1. enumerableToBoolean(? Get(Obj, "enumerable"))로 설정한다.
    2. desc.[[Enumerable]]enumerable을 할당한다.
  5. hasConfigurable을 ? HasProperty(Obj, "configurable")로 설정한다.
  6. hasConfigurabletrue이면, 다음을 수행한다:
    1. configurableToBoolean(? Get(Obj, "configurable"))로 설정한다.
    2. desc.[[Configurable]]configurable을 할당한다.
  7. hasValue를 ? HasProperty(Obj, "value")로 설정한다.
  8. hasValuetrue이면, 다음을 수행한다:
    1. value를 ? Get(Obj, "value")로 설정한다.
    2. desc.[[Value]]value를 할당한다.
  9. hasWritable을 ? HasProperty(Obj, "writable")로 설정한다.
  10. hasWritabletrue이면, 다음을 수행한다:
    1. writableToBoolean(? Get(Obj, "writable"))로 설정한다.
    2. desc.[[Writable]]writable을 할당한다.
  11. hasGet을 ? HasProperty(Obj, "get")로 설정한다.
  12. hasGettrue이면, 다음을 수행한다:
    1. getter를 ? Get(Obj, "get")로 설정한다.
    2. IsCallable(getter) 가 false이고 getterundefined가 아니면 TypeError 예외를 throw한다.
    3. desc.[[Get]]getter를 할당한다.
  13. hasSet을 ? HasProperty(Obj, "set")로 설정한다.
  14. hasSettrue이면, 다음을 수행한다:
    1. setter를 ? Get(Obj, "set")로 설정한다.
    2. IsCallable(setter) 가 false이고 setterundefined가 아니면 TypeError 예외를 throw한다.
    3. desc.[[Set]]setter를 할당한다.
  15. desc[[Get]] 필드가 있거나 desc[[Set]] 필드가 있으면, 다음을 수행한다:
    1. desc[[Value]] 필드가 있거나 desc[[Writable]] 필드가 있으면 TypeError 예외를 throw한다.
  16. desc를 반환한다.

6.2.6.6 CompletePropertyDescriptor ( Desc )

추상 연산 CompletePropertyDescriptor는 인수 Desc ( Property Descriptor )를 받아 unused를 반환한다. 호출 시 다음 단계를 수행한다:

  1. likeRecord { [[Value]]: undefined, [[Writable]]: false, [[Get]]: undefined, [[Set]]: undefined, [[Enumerable]]: false, [[Configurable]]: false }로 설정한다.
  2. IsGenericDescriptor(Desc)가 true이거나 IsDataDescriptor(Desc)가 true이면, 다음을 수행한다:
    1. Desc[[Value]] 필드가 없으면 Desc.[[Value]]like.[[Value]]로 설정한다.
    2. Desc[[Writable]] 필드가 없으면 Desc.[[Writable]]like.[[Writable]]로 설정한다.
  3. 그 외의 경우,
    1. Desc[[Get]] 필드가 없으면 Desc.[[Get]]like.[[Get]]로 설정한다.
    2. Desc[[Set]] 필드가 없으면 Desc.[[Set]]like.[[Set]]로 설정한다.
  4. Desc[[Enumerable]] 필드가 없으면 Desc.[[Enumerable]]like.[[Enumerable]]로 설정한다.
  5. Desc[[Configurable]] 필드가 없으면 Desc.[[Configurable]]like.[[Configurable]]로 설정한다.
  6. unused를 반환한다.

6.2.7 환경 레코드 명세 타입

Environment Record 타입은 중첩 함수와 블록에서의 이름 해석 동작을 설명하는 데 사용된다. 이 타입과 그에 대한 연산들은 9.1에 정의되어 있다.

6.2.8 추상 클로저 명세 타입

Abstract Closure 명세 타입은 알고리즘 단계와 값들의 집합을 함께 참조하는 데 사용된다. Abstract Closure는 메타값이며, closure(arg1, arg2)와 같은 함수 호출 방식으로 호출된다. 추상 연산과 마찬가지로, 호출 시 Abstract Closure에 명시된 알고리즘 단계를 수행한다.

Abstract Closure를 생성하는 알고리즘 단계에서는 "capture"라는 동사 뒤에 별칭(alias) 목록을 사용해 값을 캡처한다. Abstract Closure가 생성될 때, 각 별칭에 연결된 값을 그 시점에 캡처한다. Abstract Closure가 호출될 때 수행할 알고리즘을 명시하는 단계에서는, 캡처된 각 값은 해당 별칭을 통해 참조된다.

Abstract Closure가 Completion Record를 반환하는 경우, 해당 Completion Record정상 완료 또는 throw 완료여야 한다.

Abstract Closure는 다음 예시처럼 다른 알고리즘의 일부로 인라인으로 생성된다.

  1. addend를 41로 한다.
  2. closure를 매개변수 (x)를 가지며 addend를 캡처하고, 호출 시 다음 단계를 수행하는 새로운 Abstract Closure로 한다:
    1. x + addend를 반환한다.
  3. valclosure(1)로 한다.
  4. Assert: val은 42이다.

6.2.9 데이터 블록

Data Block 명세 타입은 구분되는 변경 가능한 바이트 크기(8비트) 정수 값들의 시퀀스를 설명하는 데 사용된다. byte value정수이며, 구간 [0, 255]에 속한다. Data Block 값은 고정된 개수의 바이트로 생성되며, 각 바이트의 초기값은 0이다.

이 명세 내 표기상의 편의를 위해, 배열과 유사한 문법을 사용해 Data Block 값의 개별 바이트에 접근할 수 있다. 이 표기법은 Data Block 값을 0부터 시작하는 정수-인덱스 바이트 시퀀스로 나타낸다. 예를 들어, db가 5바이트 Data Block 값이면 db[2]는 세 번째 바이트를 의미한다.

여러 agent에서 동시에 참조할 수 있는 메모리에 위치한 데이터 블록은 Shared Data Block으로 지정된다. Shared Data Block은 정체성(동등성 판단 목적)을 주소와 무관하게 가진다: 이는 프로세스의 가상 주소가 아니라 그 블록이 대표하는 메모리 위치 집합에 묶여 있다. 두 데이터 블록이 동일하다는 것은 그들이 포함하는 위치 집합이 동일할 때뿐이다. 그렇지 않으면 서로 다르며, 각자 위치 집합의 교집합은 없다. 마지막으로 Shared Data Block은 일반 Data Block과 구별된다.

Shared Data Block의 의미는 Shared Data Block 이벤트메모리 모델에 의해 정의된다. 아래 추상 연산들은 Shared Data Block 이벤트를 도입하며, 평가 의미와 메모리 모델의 이벤트 의미를 연결하는 인터페이스 역할을 한다. 이벤트들은 candidate execution을 구성하며, 메모리 모델이 필터로 작동한다. 전체 의미는 메모리 모델를 참조할 것.

Shared Data Block 이벤트Record로 모델링되며, 메모리 모델에 정의되어 있다.

Data Block 값을 다루기 위해 이 명세에서는 다음 추상 연산들이 사용된다:

6.2.9.1 CreateByteDataBlock ( size )

추상 연산 CreateByteDataBlock은 size (음이 아닌 정수)를 인수로 받아, 특정 값을 포함하는 정상 완료 Data Block 또는 throw 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. size > 253 - 1이면 RangeError 예외를 throw한다.
  2. dbsize 바이트로 구성된 새로운 Data Block 값으로 한다. 만약 그런 Data Block의 생성을 할 수 없는 경우 RangeError 예외를 throw한다.
  3. db의 모든 바이트를 0으로 설정한다.
  4. db를 반환한다.

6.2.9.2 CreateSharedByteDataBlock ( size )

추상 연산 CreateSharedByteDataBlock은 size (음이 아닌 정수) 를 인수로 받아, 특정 값을 포함하는 정상 완료 Shared Data Block 또는 throw 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. dbsize 바이트로 구성된 새로운 Shared Data Block 값으로 한다. 그런 Shared Data Block의 생성을 할 수 없는 경우 RangeError 예외를 throw한다.
  2. execution주변 agentAgent Record[[CandidateExecution]] 필드로 한다.
  3. eventsRecordexecution.[[EventsRecords]][[AgentSignifier]]AgentSignifier()인 Agent Events Record로 한다.
  4. zero를 « 0 »으로 한다.
  5. db의 각 인덱스 i에 대해, 다음을 수행한다:
    1. WriteSharedMemory { [[Order]]: init, [[NoTear]]: true, [[Block]]: db, [[ByteIndex]]: i, [[ElementSize]]: 1, [[Payload]]: zero }를 eventsRecord.[[EventList]]에 추가한다.
  6. db를 반환한다.

6.2.9.3 CopyDataBlockBytes ( toBlock, toIndex, fromBlock, fromIndex, count )

추상 연산 CopyDataBlockBytes는 인수 toBlock ( Data Block 또는 Shared Data Block ), toIndex (음이 아닌 정수), fromBlock ( Data Block 또는 Shared Data Block ), fromIndex (음이 아닌 정수), count (음이 아닌 정수)를 받아 unused를 반환한다. 호출 시 다음 단계를 수행한다:

  1. Assert: fromBlocktoBlock은 서로 다른 값이어야 한다.
  2. fromSizefromBlock의 바이트 수로 한다.
  3. Assert: fromIndex + countfromSize 여야 한다.
  4. toSizetoBlock의 바이트 수로 한다.
  5. Assert: toIndex + counttoSize 여야 한다.
  6. count > 0인 동안 반복한다:
    1. fromBlockShared Data Block이면, 다음을 수행한다:
      1. execution주변 agentAgent Record[[CandidateExecution]] 필드로 한다.
      2. eventsRecordexecution.[[EventsRecords]][[AgentSignifier]]AgentSignifier()인 Agent Events Record로 한다.
      3. bytesList로, 유일한 요소는 비결정적으로 선택된 byte value로 한다.
      4. 참고: 구현에서는 bytes가 하드웨어의 비원자적 읽기 명령의 결과일 수 있다. 이 비결정성은 메모리 모델의 의미 처방으로, 약한 일관성을 가진 하드웨어의 관찰 가능한 동작을 설명한다.
      5. readEventReadSharedMemory { [[Order]]: unordered, [[NoTear]]: true, [[Block]]: fromBlock, [[ByteIndex]]: fromIndex, [[ElementSize]]: 1 }로 한다.
      6. readEventeventsRecord.[[EventList]]에 추가한다.
      7. Chosen Value Record { [[Event]]: readEvent, [[ChosenValue]]: bytes }를 execution.[[ChosenValues]]에 추가한다.
      8. toBlockShared Data Block이면, 다음을 수행한다:
        1. WriteSharedMemory { [[Order]]: unordered, [[NoTear]]: true, [[Block]]: toBlock, [[ByteIndex]]: toIndex, [[ElementSize]]: 1, [[Payload]]: bytes } 를 eventsRecord.[[EventList]]에 추가한다.
      9. 그 외의 경우,
        1. toBlock[toIndex]에 bytes[0]을 설정한다.
    2. 그 외의 경우,
      1. Assert: toBlockShared Data Block이 아니어야 한다.
      2. toBlock[toIndex]에 fromBlock[fromIndex]를 설정한다.
    3. toIndextoIndex + 1로 한다.
    4. fromIndexfromIndex + 1로 한다.
    5. countcount - 1로 한다.
  7. unused를 반환한다.

6.2.10 PrivateElement 명세 타입

PrivateElement 타입은 private 클래스 필드, 메서드, 접근자의 명세에 사용되는 Record이다. Property Descriptor는 private 요소에 사용되지 않지만, private 필드는 비구성, 비열거, 쓰기 가능한 데이터 프로퍼티와 유사하게 동작하고, private 메서드는 비구성, 비열거, 쓰기 불가능한 데이터 프로퍼티와 유사하며, private 접근자는 비구성, 비열거 접근자 프로퍼티와 유사하게 동작한다.

PrivateElement 타입의 값은 Record 값이며, 그 필드는 표 9에 정의되어 있다. 이러한 값은 PrivateElements라 한다.

표 9: PrivateElement 필드
필드 이름 해당 필드가 존재하는 [[Kind]] 필드의 값 의미
[[Key]] 모두 Private Name 필드, 메서드, 접근자의 이름.
[[Kind]] 모두 field, method, 또는 accessor 요소의 종류.
[[Value]] fieldmethod ECMAScript 언어 값 필드의 값.
[[Get]] accessor 함수 객체 또는 undefined private 접근자의 getter.
[[Set]] accessor 함수 객체 또는 undefined private 접근자의 setter.

6.2.11 ClassFieldDefinition Record 명세 타입

ClassFieldDefinition 타입은 클래스 필드 명세에 사용되는 Record이다.

ClassFieldDefinition 타입의 값은 Record 값이며, 그 필드는 표 10에 정의되어 있다. 이러한 값은 ClassFieldDefinition Record라 한다.

표 10: ClassFieldDefinition Record 필드
필드 이름 의미
[[Name]] Private Name, 문자열, 또는 심볼 필드의 이름.
[[Initializer]] ECMAScript 함수 객체 또는 empty 해당하는 경우, 필드의 이니셜라이저.

6.2.12 Private Name

Private Name 명세 타입은 전역적으로 고유한 값(다른 Private Name과 구분되는 값, 비록 외견상 구별이 불가능하더라도)으로, private 클래스 요소(필드, 메서드, 접근자)의 키를 나타내는 데 사용된다. 각 Private Name은 불변의 [[Description]]을 가지며, 이는 문자열 값이다. Private Name은 PrivateFieldAdd 또는 PrivateMethodOrAccessorAdd로 어떤 ECMAScript 객체에도 설치할 수 있으며, PrivateGetPrivateSet을 사용해 읽거나 쓸 수 있다.

6.2.13 ClassStaticBlockDefinition 레코드 명세 타입

ClassStaticBlockDefinition Record는 클래스 정적 초기화 블록의 실행 가능한 코드를 캡슐화하는 데 사용되는 Record 값이다.

ClassStaticBlockDefinition Record는 표 11에 나열된 필드를 가진다.

표 11: ClassStaticBlockDefinition Record 필드
필드 이름 의미
[[BodyFunction]] ECMAScript 함수 객체 클래스의 정적 초기화 시 호출되는 함수 객체

7 추상 연산

이 연산들은 ECMAScript 언어의 일부가 아니며, 오직 ECMAScript 언어 의미의 명세를 돕기 위해 여기에 정의되어 있다. 다른, 더 특화된 추상 연산들은 이 명세 전반에 걸쳐 정의되어 있다.

7.1 타입 변환

ECMAScript 언어는 필요에 따라 암시적으로 자동 타입 변환을 수행한다. 특정 구문의 의미를 명확히 하기 위해 일련의 변환 추상 연산을 정의하는 것이 유용하다. 변환 추상 연산들은 다형적이며, 어떤 ECMAScript 언어 타입의 값도 인수로 받을 수 있다. 하지만 다른 명세 타입은 이 연산들과 함께 사용되지 않는다.

BigInt 타입은 ECMAScript 언어에서 암시적 변환을 가지지 않는다. 프로그래머는 다른 타입의 값을 변환하려면 BigInt를 명시적으로 호출해야 한다.

7.1.1 ToPrimitive ( input [ , preferredType ] )

추상 연산 ToPrimitive는 인수 input (ECMAScript 언어 값)과 선택적 인수 preferredType (string 또는 number)을 받아, 특정 값을 포함하는 정상 완료 ECMAScript 언어 값 또는 throw 완료를 반환한다. 이 연산은 input 인수를 Object 타입이 아닌 값으로 변환한다. 만약 객체가 둘 이상의 원시 타입으로 변환 가능하다면, 선택적 힌트 preferredType을 사용해 그 타입을 우선시할 수 있다. 호출 시 다음 단계를 수행한다:

  1. input객체이면, 다음을 수행한다:
    1. exoticToPrim를 ? GetMethod(input, %Symbol.toPrimitive%)로 한다.
    2. exoticToPrimundefined가 아니면, 다음을 수행한다:
      1. preferredType이 없으면, 다음을 수행한다:
        1. hint"default"로 한다.
      2. 그 외 preferredTypestring이면, 다음을 수행한다:
        1. hint"string"로 한다.
      3. 그 외의 경우,
        1. Assert: preferredTypenumber임을 보장한다.
        2. hint"number"로 한다.
      4. result를 ? Call(exoticToPrim, input, « hint »)로 한다.
      5. result객체가 아니면, result를 반환한다.
      6. TypeError 예외를 throw한다.
    3. preferredType이 없으면 preferredTypenumber로 한다.
    4. OrdinaryToPrimitive(input, preferredType)를 반환한다.
  2. input을 반환한다.
참고

ToPrimitive가 힌트 없이 호출될 때 기본적으로 number 힌트로 동작한다. 그러나 객체는 %Symbol.toPrimitive% 메서드를 정의함으로써 이 동작을 오버라이드할 수 있다. 이 명세에서 정의된 객체 중 Date( 21.4.4.45 참고 )와 Symbol 객체( 20.4.3.5 참고 )만이 기본 ToPrimitive 동작을 오버라이드한다. Date는 힌트가 없을 때 string으로 동작한다.

7.1.1.1 OrdinaryToPrimitive ( O, hint )

추상 연산 OrdinaryToPrimitive는 인수 O(객체)와 hint(string 또는 number)를 받아, 특정 값을 포함하는 정상 완료 ECMAScript 언어 값 또는 throw 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. hintstring이면, 다음을 수행한다:
    1. methodNames를 « "toString", "valueOf" »로 한다.
  2. 그 외의 경우,
    1. methodNames를 « "valueOf", "toString" »로 한다.
  3. methodNames의 각 요소 name에 대해, 다음을 수행한다:
    1. method를 ? Get(O, name)로 한다.
    2. IsCallable(method) 가 true이면, 다음을 수행한다:
      1. result를 ? Call(method, O)로 한다.
      2. result객체가 아니면, result를 반환한다.
  4. TypeError 예외를 throw한다.

7.1.2 ToBoolean ( argument )

추상 연산 ToBoolean은 인수 argument (ECMAScript 언어 값)를 받아 Boolean을 반환한다. 이 연산은 argument를 Boolean 타입 값으로 변환한다. 호출 시 다음 단계를 수행한다:

  1. argumentBoolean이면, argument를 반환한다.
  2. argumentundefined, null, +0𝔽, -0𝔽, NaN, 0, 또는 빈 문자열 중 하나이면 false를 반환한다.
  3. 참고: 이 단계는 B.3.6.1 절에서 대체된다.
  4. true를 반환한다.

7.1.3 ToNumeric ( value )

추상 연산 ToNumeric은 인수 value (ECMAScript 언어 값)를 받아, 특정 값을 포함하는 정상 완료 Number 또는 BigInt, 또는 throw 완료를 반환한다. 이 연산은 value를 Number 또는 BigInt로 변환해 반환한다. 호출 시 다음 단계를 수행한다:

  1. primValue를 ? ToPrimitive(value, number)로 한다.
  2. primValueBigInt이면, primValue를 반환한다.
  3. ToNumber(primValue)를 반환한다.

7.1.4 ToNumber ( argument )

추상 연산 ToNumber는 인수 argument (ECMAScript 언어 값)를 받아, 특정 값을 포함하는 정상 완료 Number 또는 throw 완료를 반환한다. 이 연산은 argument를 Number 타입 값으로 변환한다. 호출 시 다음 단계를 수행한다:

  1. argumentNumber이면, argument를 반환한다.
  2. argument가 Symbol 또는 BigInt이면, TypeError 예외를 throw한다.
  3. argumentundefined이면 NaN을 반환한다.
  4. argumentnull 또는 false이면 +0𝔽을 반환한다.
  5. argumenttrue이면 1𝔽을 반환한다.
  6. argument문자열이면, StringToNumber(argument)를 반환한다.
  7. Assert: argument객체임을 보장한다.
  8. primValue를 ? ToPrimitive(argument, number)로 한다.
  9. Assert: primValue객체가 아님을 보장한다.
  10. ToNumber(primValue)를 반환한다.

7.1.4.1 문자열 타입에 적용된 ToNumber

추상 연산 StringToNumber는 다음 문법을 사용해 문자열 값을 Number 값으로 변환하는 방법을 명세한다.

구문

StringNumericLiteral ::: StrWhiteSpaceopt StrWhiteSpaceopt StrNumericLiteral StrWhiteSpaceopt StrWhiteSpace ::: StrWhiteSpaceChar StrWhiteSpaceopt StrWhiteSpaceChar ::: WhiteSpace LineTerminator StrNumericLiteral ::: StrDecimalLiteral NonDecimalIntegerLiteral[~Sep] StrDecimalLiteral ::: StrUnsignedDecimalLiteral + StrUnsignedDecimalLiteral - StrUnsignedDecimalLiteral StrUnsignedDecimalLiteral ::: Infinity DecimalDigits[~Sep] . DecimalDigits[~Sep]opt ExponentPart[~Sep]opt . DecimalDigits[~Sep] ExponentPart[~Sep]opt DecimalDigits[~Sep] ExponentPart[~Sep]opt

위에 명시적으로 정의되지 않은 모든 문법 기호는 숫자 리터럴에 대한 어휘 문법(12.9.3)에서 사용된 정의를 따른다.

참고

StringNumericLiteralNumericLiteral의 구문에는 몇 가지 차이가 있다는 점에 유의해야 한다:

7.1.4.1.1 StringToNumber ( str )

추상 연산 StringToNumber는 인수 str(문자열)을 받아 Number를 반환한다. 호출 시 다음 단계를 수행한다:

  1. literalParseText(str, StringNumericLiteral)로 한다.
  2. literal오류의 리스트이면 NaN을 반환한다.
  3. literalStringNumericValue를 반환한다.

7.1.4.1.2 런타임 의미: StringNumericValue

구문 지시 연산 StringNumericValue는 인수를 받지 않고 Number를 반환한다.

참고

StringNumericLiteral을 Number 값으로 변환하는 과정은 전체적으로 NumericValueNumericLiteral에 대해 결정되는 과정( 12.9.3 참고 )과 유사하지만, 세부 사항은 약간 다르다.

다음 생성 규칙별로 조각(piecewise) 정의된다:

StringNumericLiteral ::: StrWhiteSpaceopt
  1. +0𝔽을 반환한다.
StringNumericLiteral ::: StrWhiteSpaceopt StrNumericLiteral StrWhiteSpaceopt
  1. StrNumericLiteralStringNumericValue를 반환한다.
StrNumericLiteral ::: NonDecimalIntegerLiteral
  1. 𝔽(MV of NonDecimalIntegerLiteral)를 반환한다.
StrDecimalLiteral ::: - StrUnsignedDecimalLiteral
  1. aStrUnsignedDecimalLiteralStringNumericValue로 한다.
  2. a+0𝔽이면 -0𝔽을 반환한다.
  3. -a를 반환한다.
StrUnsignedDecimalLiteral ::: Infinity
  1. +∞𝔽을 반환한다.
StrUnsignedDecimalLiteral ::: DecimalDigits . DecimalDigitsopt ExponentPartopt
  1. 첫 번째 DecimalDigits의 MV를 a로 한다.
  2. 두 번째 DecimalDigits가 존재하면, 다음을 수행한다:
    1. 두 번째 DecimalDigits의 MV를 b로 한다.
    2. 두 번째 DecimalDigits의 코드 포인트 개수를 n으로 한다.
  3. 그 외의 경우,
    1. b를 0으로 한다.
    2. n을 0으로 한다.
  4. ExponentPart가 존재하면, eExponentPart의 MV로 한다. 그렇지 않으면 e를 0으로 한다.
  5. RoundMVResult((a + (b × 10-n)) × 10e)를 반환한다.
StrUnsignedDecimalLiteral ::: . DecimalDigits ExponentPartopt
  1. DecimalDigits의 MV를 b로 한다.
  2. ExponentPart가 존재하면, eExponentPart의 MV로 한다. 그렇지 않으면 e를 0으로 한다.
  3. DecimalDigits의 코드 포인트 개수를 n으로 한다.
  4. RoundMVResult(b × 10e - n)를 반환한다.
StrUnsignedDecimalLiteral ::: DecimalDigits ExponentPartopt
  1. DecimalDigits의 MV를 a로 한다.
  2. ExponentPart가 존재하면, eExponentPart의 MV로 한다. 그렇지 않으면 e를 0으로 한다.
  3. RoundMVResult(a × 10e)를 반환한다.

7.1.4.1.3 RoundMVResult ( n )

추상 연산 RoundMVResult는 인수 n(수학적 값)을 받아 Number를 반환한다. 이 연산은 n구현 정의 방식으로 Number로 변환한다. 이 추상 연산에서, 숫자는 0이 아니거나 왼쪽에 0이 아닌 숫자가 있고 오른쪽에도 0이 아닌 숫자가 있을 때 유효 숫자(significant)로 간주한다. 이 추상 연산에서, "수학적 값이 나타내는" 어떤 수학적 값의 표현은 "수학적 값의 10진수 표현"의 역이다. 호출 시 다음 단계를 수행한다:

  1. n의 10진수 표현이 20자리 이하의 유효 숫자를 가지면 𝔽(n)를 반환한다.
  2. option1n의 10진수 표현에서 20번째 이후의 유효 숫자를 0으로 바꾼 결과가 나타내는 수학적 값로 한다.
  3. option2n의 10진수 표현에서 20번째 이후의 유효 숫자를 0으로 바꾸고, 그 20번째 자릿수를(필요하다면 올림하면서) 1 증가시킨 결과가 나타내는 수학적 값로 한다.
  4. chosen구현 정의 방식으로 option1 또는 option2 중에서 선택한다.
  5. 𝔽(chosen)를 반환한다.

7.1.5 ToIntegerOrInfinity ( argument )

추상 연산 ToIntegerOrInfinity는 인수 argument (ECMAScript 언어 값)를 받아, 특정 값을 포함하는 정상 완료 정수, +∞, 또는 -∞, 또는 throw 완료를 반환한다. 이 연산은 argument를 Number 값의 소수 부분을 잘라낸 정수로 변환하거나, 해당 Number 값이 무한대일 경우 +∞ 또는 -∞로 변환한다. 호출 시 다음 단계를 수행한다:

  1. number를 ? ToNumber(argument)로 한다.
  2. numberNaN, +0𝔽, 또는 -0𝔽 중 하나이면 0을 반환한다.
  3. number+∞𝔽이면 +∞를 반환한다.
  4. number-∞𝔽이면 -∞를 반환한다.
  5. truncate((number))를 반환한다.
참고
𝔽(ToIntegerOrInfinity(x))는 어떤 x에 대해서도 -0𝔽을 반환하지 않는다. 소수 부분의 절단은 x수학적 값으로 변환한 후 수행된다.

7.1.6 ToInt32 ( argument )

추상 연산 ToInt32는 인수 argument (ECMAScript 언어 값)를 받아, 특정 값을 포함하는 정상 완료 정수 Number 또는 throw 완료를 반환한다. 이 연산은 argument정수 Number 232개 중 [-231, 231-1] 구간 내의 값으로 변환한다. 호출 시 다음 단계를 수행한다:

  1. number를 ? ToNumber(argument)로 한다.
  2. number유한이 아니거나 number+0𝔽 또는 -0𝔽이면 +0𝔽을 반환한다.
  3. inttruncate((number))로 한다.
  4. int32bitint modulo 232로 한다.
  5. int32bit ≥ 231이면 𝔽(int32bit - 232)를, 아니면 𝔽(int32bit)를 반환한다.
참고

위 ToInt32 정의에 따라:

  • ToInt32 추상 연산은 멱등적이다: 그것이 생성한 결과에 다시 적용하면 값이 바뀌지 않는다.
  • ToInt32(ToUint32(x))는 모든 x에 대해 ToInt32(x)와 같다. (+∞𝔽-∞𝔽+0𝔽으로 매핑되는 것은 이 속성을 보존하기 위함이다.)
  • ToInt32는 -0𝔽+0𝔽으로 매핑한다.

7.1.7 ToUint32 ( argument )

추상 연산 ToUint32는 인수 argument (ECMAScript 언어 값)를 받아, 특정 값을 포함하는 정상 완료 정수 Number 또는 throw 완료를 반환한다. 이 연산은 argument정수 Number 232개 중 [+0, 232-1] 구간 내의 값으로 변환한다. 호출 시 다음 단계를 수행한다:

  1. number를 ? ToNumber(argument)로 한다.
  2. number유한이 아니거나 number+0𝔽 또는 -0𝔽이면 +0𝔽을 반환한다.
  3. inttruncate((number))로 한다.
  4. int32bitint modulo 232로 한다.
  5. 𝔽(int32bit)를 반환한다.
참고

위 ToUint32 정의에 따라:

  • 5 단계가 ToUint32와 ToInt32의 유일한 차이점이다.
  • ToUint32 추상 연산은 멱등적이다: 그것이 생성한 결과에 다시 적용하면 값이 바뀌지 않는다.
  • ToUint32(ToInt32(x))는 모든 x에 대해 ToUint32(x)와 같다. (+∞𝔽-∞𝔽+0𝔽으로 매핑되는 것은 이 속성을 보존하기 위함이다.)
  • ToUint32는 -0𝔽+0𝔽으로 매핑한다.

7.1.8 ToInt16 ( argument )

추상 연산 ToInt16은 인수 argument (ECMAScript 언어 값)를 받아, 특정 값을 포함하는 정상 완료 정수 Number 또는 throw 완료를 반환한다. 이 연산은 argument정수 Number 216개 중 [-215, 215-1] 구간 내의 값으로 변환한다. 호출 시 다음 단계를 수행한다:

  1. number를 ? ToNumber(argument)로 한다.
  2. number유한이 아니거나 number+0𝔽 또는 -0𝔽이면 +0𝔽을 반환한다.
  3. inttruncate((number))로 한다.
  4. int16bitint modulo 216로 한다.
  5. int16bit ≥ 215이면 𝔽(int16bit - 216)를, 아니면 𝔽(int16bit)를 반환한다.

7.1.9 ToUint16 ( argument )

추상 연산 ToUint16은 인수 argument (ECMAScript 언어 값)를 받아, 특정 값을 포함하는 정상 완료 정수 Number 또는 throw 완료를 반환한다. 이 연산은 argument정수 Number 216개 중 [+0, 216-1] 구간 내의 값으로 변환한다. 호출 시 다음 단계를 수행한다:

  1. number를 ? ToNumber(argument)로 한다.
  2. number유한이 아니거나 number+0𝔽 또는 -0𝔽이면 +0𝔽을 반환한다.
  3. inttruncate((number))로 한다.
  4. int16bitint modulo 216로 한다.
  5. 𝔽(int16bit)를 반환한다.
참고

위 ToUint16 정의에 따라:

  • 4 단계의 216 대입만이 ToUint32와 ToUint16의 유일한 차이점이다.
  • ToUint16은 -0𝔽+0𝔽으로 매핑한다.

7.1.10 ToInt8 ( argument )

추상 연산 ToInt8은 인수 argument (ECMAScript 언어 값)를 받아, 특정 값을 포함하는 정상 완료 정수 Number 또는 throw 완료를 반환한다. 이 연산은 argument정수 Number 28개 중 [-128, 127] 구간 내의 값으로 변환한다. 호출 시 다음 단계를 수행한다:

  1. number를 ? ToNumber(argument)로 한다.
  2. number유한이 아니거나 number+0𝔽 또는 -0𝔽이면 +0𝔽을 반환한다.
  3. inttruncate((number))로 한다.
  4. int8bitint modulo 28로 한다.
  5. int8bit ≥ 27이면 𝔽(int8bit - 28)를, 아니면 𝔽(int8bit)를 반환한다.

7.1.11 ToUint8 ( argument )

추상 연산 ToUint8은 인수 argument (ECMAScript 언어 값)를 받아, 특정 값을 포함하는 정상 완료 정수 Number 또는 throw 완료를 반환한다. 이 연산은 argument정수 Number 28개 중 [+0, 255] 구간 내의 값으로 변환한다. 호출 시 다음 단계를 수행한다:

  1. number를 ? ToNumber(argument)로 한다.
  2. number유한이 아니거나 number+0𝔽 또는 -0𝔽이면 +0𝔽을 반환한다.
  3. inttruncate((number))로 한다.
  4. int8bitint modulo 28로 한다.
  5. 𝔽(int8bit)를 반환한다.

7.1.12 ToUint8Clamp ( argument )

추상 연산 ToUint8Clamp는 인수 argument (ECMAScript 언어 값)를 받아, 특정 값을 포함하는 정상 완료 정수 Number 또는 throw 완료를 반환한다. 이 연산은 argument를 28개의 정수 Number 값 중 [+0, 255] 구간 내로 클램프하고 반올림한다. 호출 시 다음 단계를 수행한다:

  1. number를 ? ToNumber(argument)로 한다.
  2. numberNaN이면 +0𝔽을 반환한다.
  3. mvnumber의 확장 수학적 값으로 한다.
  4. clampedmv를 0과 255 사이로 클램프한 결과로 한다.
  5. ffloor(clamped)로 한다.
  6. clamped < f + 0.5이면 𝔽(f)를 반환한다.
  7. clamped > f + 0.5이면 𝔽(f + 1)을 반환한다.
  8. f가 짝수면 𝔽(f)를, 아니면 𝔽(f + 1)을 반환한다.
참고

다른 대부분의 ECMAScript 정수 변환 연산과 달리, ToUint8Clamp는 소수 값을 절단(truncate)하지 않고 반올림(round)한다. 또한 "홀수 올림(round half up)"이 아닌 "짝수 쪽으로 반올림(round half to even)" 타이브레이킹을 사용한다. 이는 Math.round와 다르다.

7.1.13 ToBigInt ( argument )

추상 연산 ToBigInt는 인수 argument (ECMAScript 언어 값)를 받아, 특정 값을 포함하는 정상 완료 BigInt 또는 throw 완료를 반환한다. 이 연산은 argument를 BigInt 값으로 변환하거나, Number로의 암시적 변환이 필요한 경우 예외를 던진다. 호출 시 다음 단계를 수행한다:

  1. prim을 ? ToPrimitive(argument, number)로 한다.
  2. prim표 12에서 어떤 값에 해당하는지에 따라 결과를 반환한다.
표 12: BigInt 변환
인수 타입 결과
Undefined TypeError 예외를 throw한다.
Null TypeError 예외를 throw한다.
Boolean primtrue1n, false0n을 반환한다.
BigInt prim을 반환한다.
Number TypeError 예외를 throw한다.
String
  1. nStringToBigInt(prim)로 한다.
  2. nundefinedSyntaxError 예외를 throw한다.
  3. n을 반환한다.
Symbol TypeError 예외를 throw한다.

7.1.14 StringToBigInt ( str )

추상 연산 StringToBigInt는 인수 str (문자열)을 받아 BigInt 또는 undefined를 반환한다. 호출 시 다음 단계를 수행한다:

  1. literalParseText(str, StringIntegerLiteral)로 한다.
  2. literal오류의 리스트undefined를 반환한다.
  3. mvliteral의 MV로 한다.
  4. Assert: mv정수여야 한다.
  5. (mv)를 반환한다.

7.1.14.1 StringIntegerLiteral 문법

StringToBigInt는 다음 문법을 사용한다.

구문

StringIntegerLiteral ::: StrWhiteSpaceopt StrWhiteSpaceopt StrIntegerLiteral StrWhiteSpaceopt StrIntegerLiteral ::: SignedInteger[~Sep] NonDecimalIntegerLiteral[~Sep]

7.1.14.2 런타임 의미: MV

7.1.15 ToBigInt64 ( argument )

추상 연산 ToBigInt64는 인수 argument (ECMAScript 언어 값)를 받아, 특정 값을 포함하는 정상 완료 BigInt 또는 throw 완료를 반환한다. 이 연산은 argument[-263, 263-1] 구간의 264 BigInt 값 중 하나로 변환한다. 호출 시 다음 단계를 수행한다:

  1. n을 ? ToBigInt(argument)로 한다.
  2. int64bit(n) modulo 264로 한다.
  3. int64bit ≥ 263이면 (int64bit - 264)를, 아니면 (int64bit)를 반환한다.

7.1.16 ToBigUint64 ( argument )

추상 연산 ToBigUint64는 인수 argument (ECMAScript 언어 값)를 받아, 특정 값을 포함하는 정상 완료 BigInt 또는 throw 완료를 반환한다. 이 연산은 argument[0, 264-1] 구간의 264 BigInt 값 중 하나로 변환한다. 호출 시 다음 단계를 수행한다:

  1. n을 ? ToBigInt(argument)로 한다.
  2. int64bit(n) modulo 264로 한다.
  3. (int64bit)를 반환한다.

7.1.17 ToString ( argument )

추상 연산 ToString은 인수 argument (ECMAScript 언어 값)를 받아, 특정 값을 포함하는 정상 완료 문자열 또는 throw 완료를 반환한다. 이 연산은 argument를 String 타입 값으로 변환한다. 호출 시 다음 단계를 수행한다:

  1. argument문자열이면 argument를 반환한다.
  2. argument심볼이면 TypeError 예외를 throw한다.
  3. argumentundefined이면 "undefined"를 반환한다.
  4. argumentnull이면 "null"를 반환한다.
  5. argumenttrue이면 "true"를 반환한다.
  6. argumentfalse이면 "false"를 반환한다.
  7. argumentNumber이면 Number::toString(argument, 10)을 반환한다.
  8. argumentBigInt이면 BigInt::toString(argument, 10)을 반환한다.
  9. Assert: argument객체임을 보장한다.
  10. primValue를 ? ToPrimitive(argument, string)로 한다.
  11. Assert: primValue객체가 아님을 보장한다.
  12. ToString(primValue)를 반환한다.

7.1.18 ToObject ( argument )

추상 연산 ToObject는 인수 argument (ECMAScript 언어 값)를 받아, 특정 값을 포함하는 정상 완료 객체 또는 throw 완료를 반환한다. 이 연산은 argument표 13에 따라 객체 타입 값으로 변환한다:

표 13: ToObject 변환
인수 타입 결과
Undefined TypeError 예외를 throw한다.
Null TypeError 예외를 throw한다.
Boolean [[BooleanData]] 내부 슬롯이 argument로 설정된 새로운 Boolean 객체를 반환한다. Boolean 객체에 대한 설명은 20.3 참고.
Number [[NumberData]] 내부 슬롯이 argument로 설정된 새로운 Number 객체를 반환한다. Number 객체에 대한 설명은 21.1 참고.
String [[StringData]] 내부 슬롯이 argument로 설정된 새로운 String 객체를 반환한다. String 객체에 대한 설명은 22.1 참고.
Symbol [[SymbolData]] 내부 슬롯이 argument로 설정된 새로운 Symbol 객체를 반환한다. Symbol 객체에 대한 설명은 20.4 참고.
BigInt [[BigIntData]] 내부 슬롯이 argument로 설정된 새로운 BigInt 객체를 반환한다. BigInt 객체에 대한 설명은 21.2 참고.
Object argument를 반환한다.

7.1.19 ToPropertyKey ( argument )

추상 연산 ToPropertyKey는 인수 argument (ECMAScript 언어 값)를 받아, 특정 값을 포함하는 정상 완료 프로퍼티 키 또는 throw 완료를 반환한다. 이 연산은 argument프로퍼티 키로 사용할 수 있는 값으로 변환한다. 호출 시 다음 단계를 수행한다:

  1. key를 ? ToPrimitive(argument, string)로 한다.
  2. key심볼이면, 다음을 수행한다:
    1. key를 반환한다.
  3. ToString(key)를 반환한다.

7.1.20 ToLength ( argument )

추상 연산 ToLength는 인수 argument (ECMAScript 언어 값)를 받아, 특정 값을 포함하는 정상 완료 음이 아닌 정수 Number 또는 throw 완료를 반환한다. 이 연산은 argument를 배열과 유사한 객체의 길이로 사용하기에 적합한 음이 아닌 정수 Number로 클램프 및 절단한다. 호출 시 다음 단계를 수행한다:

  1. len을 ? ToIntegerOrInfinity(argument)로 한다.
  2. len ≤ 0이면 +0𝔽을 반환한다.
  3. 𝔽(min(len, 253 - 1))를 반환한다.

7.1.21 CanonicalNumericIndexString ( argument )

추상 연산 CanonicalNumericIndexString는 인수 argument(문자열)를 받아 Number 또는 undefined를 반환한다. argument"-0"이거나 어떤 Number 값 n에 대해 ToString(n)과 정확히 일치하면, 해당 Number 값을 반환한다. 그렇지 않으면 undefined를 반환한다. 호출 시 다음 단계를 수행한다:

  1. argument"-0"이면 -0𝔽을 반환한다.
  2. n을 ! ToNumber(argument)로 한다.
  3. ToString(n)이 argument와 같으면 n을 반환한다.
  4. undefined를 반환한다.

표준 숫자 문자열(canonical numeric string)은 CanonicalNumericIndexString 추상 연산이 undefined를 반환하지 않는 모든 문자열이다.

7.1.22 ToIndex ( value )

추상 연산 ToIndex는 인수 value (ECMAScript 언어 값)를 받아, 특정 값을 포함하는 정상 완료 음이 아닌 정수 또는 throw 완료를 반환한다. 이 연산은 value정수로 변환하고, 그 값이 음이 아니면서 정수 인덱스에 해당하면 그 정수를 반환한다. 그렇지 않으면 예외를 던진다. 호출 시 다음 단계를 수행한다:

  1. integer를 ? ToIntegerOrInfinity(value)로 한다.
  2. integer[0, 253 - 1] 구간에 없으면 RangeError 예외를 throw한다.
  3. integer를 반환한다.

7.2 테스트 및 비교 연산

7.2.1 RequireObjectCoercible ( argument )

추상 연산 RequireObjectCoercible는 인수 argument (ECMAScript 언어 값)를 받아, 특정 값을 포함하는 정상 완료 ECMAScript 언어 값 또는 throw 완료를 반환한다. 이 연산은 argumentToObject를 통해 객체로 변환할 수 없을 경우 오류를 던진다. 표 14에 정의되어 있다:

표 14: RequireObjectCoercible 결과
인수 타입 결과
Undefined TypeError 예외를 throw한다.
Null TypeError 예외를 throw한다.
Boolean argument를 반환한다.
Number argument를 반환한다.
String argument를 반환한다.
Symbol argument를 반환한다.
BigInt argument를 반환한다.
Object argument를 반환한다.

7.2.2 IsArray ( argument )

추상 연산 IsArray는 인수 argument (ECMAScript 언어 값)를 받아, 특정 값을 포함하는 정상 완료 Boolean 또는 throw 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. argument객체가 아니면 false를 반환한다.
  2. argumentArray 이그조틱 객체이면 true를 반환한다.
  3. argumentProxy 이그조틱 객체이면, 다음을 수행한다:
    1. ValidateNonRevokedProxy(argument)를 수행한다.
    2. proxyTargetargument.[[ProxyTarget]]로 한다.
    3. IsArray(proxyTarget)를 반환한다.
  4. false를 반환한다.

7.2.3 IsCallable ( argument )

추상 연산 IsCallable은 인수 argument (ECMAScript 언어 값)를 받아 Boolean을 반환한다. 이 연산은 argument[[Call]] 내부 메서드를 가진 호출 가능한 함수인지 판단한다. 호출 시 다음 단계를 수행한다:

  1. argument객체가 아니면 false를 반환한다.
  2. argument[[Call]] 내부 메서드를 가지고 있으면 true를 반환한다.
  3. false를 반환한다.

7.2.4 IsConstructor ( argument )

추상 연산 IsConstructor는 인수 argument (ECMAScript 언어 값)를 받아 Boolean을 반환한다. 이 연산은 argument함수 객체이면서 [[Construct]] 내부 메서드를 갖는지 판단한다. 호출 시 다음 단계를 수행한다:

  1. argument객체가 아니면 false를 반환한다.
  2. argument[[Construct]] 내부 메서드를 가지고 있으면 true를 반환한다.
  3. false를 반환한다.

7.2.5 IsExtensible ( O )

추상 연산 IsExtensible은 인수 O(객체)를 받아, 특정 값을 포함하는 정상 완료 Boolean 또는 throw 완료를 반환한다. 이 연산은 O에 추가 프로퍼티를 추가할 수 있는지 판단하는 데 사용된다. 호출 시 다음 단계를 수행한다:

  1. O.[[IsExtensible]]()를 반환한다.

7.2.6 IsRegExp ( argument )

추상 연산 IsRegExp는 인수 argument (ECMAScript 언어 값)를 받아, 특정 값을 포함하는 정상 완료 Boolean 또는 throw 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. argument객체가 아니면 false를 반환한다.
  2. matcher를 ? Get(argument, %Symbol.match%)로 한다.
  3. matcherundefined가 아니면, ToBoolean(matcher)를 반환한다.
  4. argument[[RegExpMatcher]] 내부 슬롯을 가지고 있으면 true를 반환한다.
  5. false를 반환한다.

7.2.7 정적 의미: IsStringWellFormedUnicode ( string )

추상 연산 IsStringWellFormedUnicode는 인수 string(문자열)을 받아 Boolean을 반환한다. string6.1.4에서 설명된 대로 UTF-16 인코딩 코드 포인트의 시퀀스로 해석하고, 이것이 well formed한 UTF-16 시퀀스인지 판단한다. 호출 시 다음 단계를 수행한다:

  1. lenstring의 길이로 한다.
  2. k를 0으로 한다.
  3. k < len인 동안 반복한다:
    1. cpCodePointAt(string, k)로 한다.
    2. cp.[[IsUnpairedSurrogate]]true이면 false를 반환한다.
    3. kk + cp.[[CodeUnitCount]]로 설정한다.
  4. true를 반환한다.

7.2.8 SameType ( x, y )

추상 연산 SameType은 인수 x(ECMAScript 언어 값)와 y(ECMAScript 언어 값)를 받아 Boolean을 반환한다. 두 인수가 동일한 타입인지 판별한다. 호출 시 다음 단계를 수행한다:

  1. xundefined이고 yundefined이면 true를 반환한다.
  2. xnull이고 ynull이면 true를 반환한다.
  3. xBoolean이고 yBoolean이면 true를 반환한다.
  4. xNumber이고 yNumber이면 true를 반환한다.
  5. xBigInt이고 yBigInt이면 true를 반환한다.
  6. xSymbol이고 ySymbol이면 true를 반환한다.
  7. xString이고 yString이면 true를 반환한다.
  8. x객체이고 y객체이면 true를 반환한다.
  9. false를 반환한다.

7.2.9 SameValue ( x, y )

추상 연산 SameValue는 인수 x(ECMAScript 언어 값)와 y(ECMAScript 언어 값)를 받아 Boolean을 반환한다. 두 인수가 같은 값인지 판단한다. 호출 시 다음 단계를 수행한다:

  1. SameType(x, y)가 false이면 false를 반환한다.
  2. xNumber이면, 다음을 수행한다:
    1. Number::sameValue(x, y)를 반환한다.
  3. SameValueNonNumber(x, y)를 반환한다.
참고

이 알고리즘은 IsStrictlyEqual 알고리즘과는 모든 NaN 값을 동일하게 취급하고 +0𝔽-0𝔽을 구분한다는 점에서 다르다.

7.2.10 SameValueZero ( x, y )

추상 연산 SameValueZero는 인수 x(ECMAScript 언어 값)와 y(ECMAScript 언어 값)를 받아 Boolean을 반환한다. 두 인수가 같은 값인지 판단하되, +0𝔽-0𝔽의 차이를 무시한다. 호출 시 다음 단계를 수행한다:

  1. SameType(x, y)가 false이면 false를 반환한다.
  2. xNumber이면, 다음을 수행한다:
    1. Number::sameValueZero(x, y)를 반환한다.
  3. SameValueNonNumber(x, y)를 반환한다.
참고

SameValueZero는 SameValue와 다르게 +0𝔽-0𝔽을 동일하게 취급한다.

7.2.11 SameValueNonNumber ( x, y )

추상 연산 SameValueNonNumber는 인수 x(ECMAScript 언어 값, Number 제외)와 y(ECMAScript 언어 값, Number 제외)를 받아 Boolean을 반환한다. 호출 시 다음 단계를 수행한다:

  1. Assert: SameType(x, y)가 true임을 보장한다.
  2. xundefined 또는 null이면 true를 반환한다.
  3. xBigInt이면, 다음을 수행한다:
    1. BigInt::equal(x, y)를 반환한다.
  4. xString이면, 다음을 수행한다:
    1. xy가 길이가 같고 모든 위치의 코드 유닛이 같으면 true를, 그렇지 않으면 false를 반환한다.
  5. xBoolean이면, 다음을 수행한다:
    1. xy가 모두 true이거나 모두 false이면 true를, 그렇지 않으면 false를 반환한다.
  6. 참고: 다른 모든 ECMAScript 언어 값은 동일성(identity)으로 비교한다.
  7. xy와 동일하면 true를, 그렇지 않으면 false를 반환한다.
참고 1
설명 목적으로 일부 경우가 불필요하게 별도로 처리되어 있다.
참고 2
"xy와 동일하다"의 구체적인 의미는 5.2.7에 자세히 설명되어 있다.

7.2.12 IsLessThan ( x, y, LeftFirst )

추상 연산 IsLessThan은 인수 x(ECMAScript 언어 값), y(ECMAScript 언어 값), LeftFirst(Boolean)을 받아, 특정 값을 포함하는 정상 완료 Boolean 또는 undefined, 또는 throw 완료를 반환한다. 이 연산은 비교 x < y의 의미를 제공하며, true, false, undefined(피연산자 중 하나 이상이 NaN인 경우)을 반환한다. LeftFirst 플래그는 xy에 부수 효과가 있을 수 있을 때 연산의 순서를 제어하는 데 사용된다. 호출 시 다음 단계를 수행한다:

  1. LeftFirsttrue이면, 다음을 수행한다:
    1. px를 ? ToPrimitive(x, number)로 한다.
    2. py를 ? ToPrimitive(y, number)로 한다.
  2. 그 외의 경우:
    1. 참고: 평가 순서를 유지하기 위해 평가 순서를 반대로 한다.
    2. py를 ? ToPrimitive(y, number)로 한다.
    3. px를 ? ToPrimitive(x, number)로 한다.
  3. px문자열이고 py문자열이면, 다음을 수행한다:
    1. lxpx의 길이로 한다.
    2. lypy의 길이로 한다.
    3. 0 ≤ i < min(lx, ly)인 모든 정수 i에 대해, 오름차순으로 다음을 수행한다:
      1. cxpx의 인덱스 i에 있는 코드 유닛의 숫자 값으로 한다.
      2. cypy의 인덱스 i에 있는 코드 유닛의 숫자 값으로 한다.
      3. cx < cy이면 true를 반환한다.
      4. cx > cy이면 false를 반환한다.
    4. lx < ly이면 true를, 아니면 false를 반환한다.
  4. 그 외의 경우:
    1. pxBigInt이고 py문자열이면, 다음을 수행한다:
      1. nyStringToBigInt(py)로 한다.
      2. nyundefined이면 undefined를 반환한다.
      3. BigInt::lessThan(px, ny)를 반환한다.
    2. px문자열이고 pyBigInt이면, 다음을 수행한다:
      1. nxStringToBigInt(px)로 한다.
      2. nxundefined이면 undefined를 반환한다.
      3. BigInt::lessThan(nx, py)를 반환한다.
    3. 참고: pxpy는 원시값이므로 평가 순서는 중요하지 않다.
    4. nx를 ? ToNumeric(px)로 한다.
    5. ny를 ? ToNumeric(py)로 한다.
    6. SameType(nx, ny)가 true이면, 다음을 수행한다:
      1. nxNumber이면, 다음을 수행한다:
        1. Number::lessThan(nx, ny)를 반환한다.
      2. 그 외의 경우:
        1. Assert: nxBigInt임을 보장한다.
        2. BigInt::lessThan(nx, ny)를 반환한다.
    7. Assert: nxBigInt이고 nyNumber이거나, nxNumber이고 nyBigInt임을 보장한다.
    8. nx 또는 nyNaN이면 undefined를 반환한다.
    9. nx-∞𝔽이거나 ny+∞𝔽이면 true를 반환한다.
    10. nx+∞𝔽이거나 ny-∞𝔽이면 false를 반환한다.
    11. (nx) < (ny)이면 true를, 아니면 false를 반환한다.
참고 1

3 단계는 1.c ( 13.15.3 )에서 논리합 대신 논리곱을 사용한다는 점에서 다르다.

참고 2

문자열의 비교는 UTF-16 코드 유닛의 시퀀스에 대한 단순한 사전식(lexicographic) 정렬을 사용한다. 유니코드 명세에 정의된 문자/문자열 동등성 및 정렬 순서의 더 복잡하고 의미론적인 정의는 사용하지 않는다. 따라서 유니코드 표준에서 정규적으로 동등하지만 정규화 형식이 다른 String 값은 같지 않다고 판정될 수 있다. 또한, 코드 유닛 기준 사전식 정렬은 서러게이트 쌍이 포함된 문자열의 코드 포인트 기준 정렬과 다를 수 있다.

7.2.13 IsLooselyEqual ( x, y )

추상 연산 IsLooselyEqual는 인수 x(ECMAScript 언어 값)와 y(ECMAScript 언어 값)를 받아, 특정 값을 포함하는 정상 완료 Boolean 또는 throw 완료를 반환한다. 이 연산은 == 연산자의 의미를 제공한다. 호출 시 다음 단계를 수행한다:

  1. SameType(x, y)가 true면, 다음을 수행한다:
    1. IsStrictlyEqual(x, y)를 반환한다.
  2. xnull이고 yundefined이면 true를 반환한다.
  3. xundefined이고 ynull이면 true를 반환한다.
  4. 참고: 이 단계는 B.3.6.2 절에서 대체된다.
  5. xNumber이고 yString이면, ! IsLooselyEqual(x, ! ToNumber(y))를 반환한다.
  6. xString이고 yNumber이면, ! IsLooselyEqual(! ToNumber(x), y)를 반환한다.
  7. xBigInt이고 yString이면, 다음을 수행한다:
    1. nStringToBigInt(y)로 한다.
    2. nundefined이면 false를 반환한다.
    3. IsLooselyEqual(x, n)을 반환한다.
  8. xString이고 yBigInt이면, ! IsLooselyEqual(y, x)를 반환한다.
  9. xBoolean이면, ! IsLooselyEqual(! ToNumber(x), y)를 반환한다.
  10. yBoolean이면, ! IsLooselyEqual(x, ! ToNumber(y))를 반환한다.
  11. x가 String, Number, BigInt, Symbol 중 하나이고 y객체이면, ! IsLooselyEqual(x, ? ToPrimitive(y))를 반환한다.
  12. x객체이고 y가 String, Number, BigInt, Symbol 중 하나이면, ! IsLooselyEqual(? ToPrimitive(x), y)를 반환한다.
  13. xBigInt이고 yNumber이거나, xNumber이고 yBigInt이면, 다음을 수행한다:
    1. x유한이 아니거나 y유한이 아니면 false를 반환한다.
    2. (x) = (y)이면 true를, 아니면 false를 반환한다.
  14. false를 반환한다.

7.2.14 IsStrictlyEqual ( x, y )

추상 연산 IsStrictlyEqual은 인수 x (ECMAScript 언어 값)와 y (ECMAScript 언어 값)를 받아 Boolean을 반환한다. 이 연산은 === 연산자의 의미를 제공한다. 호출 시 다음 단계를 수행한다:

  1. SameType(x, y)가 false이면 false를 반환한다.
  2. xNumber이면, 다음을 수행한다:
    1. Number::equal(x, y)를 반환한다.
  3. SameValueNonNumber(x, y)를 반환한다.
참고

이 알고리즘은 부호 있는 0과 NaN 처리에서 SameValue 알고리즘과 다르다.

7.3 객체에 대한 연산

7.3.1 MakeBasicObject ( internalSlotsList )

추상 연산 MakeBasicObject는 인수 internalSlotsList(내부 슬롯 이름의 List)를 받아 객체를 반환한다. 이는 일반 객체특수 객체를 포함하여 알고리즘적으로 생성되는 모든 ECMAScript 객체의 근원이다. 이는 모든 객체 생성에 사용되는 공통 단계를 분리하고 객체 생성을 중앙 집중화한다. 호출 시 다음 단계를 수행한다:

  1. internalSlotsListinternalSlotsList와 « [[PrivateElements]] »의 list-concatenation으로 설정한다.
  2. objinternalSlotsList의 각 이름에 대해 내부 슬롯을 가지는 새로 생성된 객체로 한다.
  3. 참고: 객체 내부 메서드 및 내부 슬롯에 설명된 바와 같이, 각 내부 슬롯의 초기 값은 별도로 명시되지 않는 한 undefined이다.
  4. obj.[[PrivateElements]]를 새로운 빈 List로 설정한다.
  5. obj의 필수 내부 메서드를 일반 객체10.1에 명시된 기본 정의로 설정한다.
  6. Assert: 호출자가 obj[[GetPrototypeOf]][[SetPrototypeOf]] 필수 내부 메서드를 모두 재정의하지 않는 경우, internalSlotsList[[Prototype]]을 포함한다.
  7. Assert: 호출자가 obj[[SetPrototypeOf]], [[IsExtensible]], [[PreventExtensions]] 필수 내부 메서드를 모두 재정의하지 않는 경우, internalSlotsList[[Extensible]]을 포함한다.
  8. internalSlotsList[[Extensible]]가 포함되어 있으면 obj.[[Extensible]]true로 설정한다.
  9. obj를 반환한다.
참고

이 명세 내에서 특수 객체추상 연산 (ArrayCreate, BoundFunctionCreate 등)에서 먼저 MakeBasicObject를 호출해 기본 객체를 얻고, 그 후에 해당 객체의 일부 또는 전체 내부 메서드를 재정의함으로써 생성된다. 특수 객체 생성을 캡슐화하기 위해, 객체의 필수 내부 메서드는 이러한 연산 외부에서 변경되지 않는다.

7.3.2 Get ( O, P )

추상 연산 Get은 인수 O(객체), P(프로퍼티 키)를 받아, 특정 값을 포함하는 정상 완료 ECMAScript 언어 값 또는 throw 완료를 반환한다. 이 연산은 객체의 특정 프로퍼티 값을 조회할 때 사용된다. 호출 시 다음 단계를 수행한다:

  1. O.[[Get]](P, O)를 반환한다.

7.3.3 GetV ( V, P )

추상 연산 GetV는 인수 V(ECMAScript 언어 값), P(프로퍼티 키)를 받아, 특정 값을 포함하는 정상 완료 ECMAScript 언어 값 또는 throw 완료를 반환한다. 이 연산은 ECMAScript 언어 값의 특정 프로퍼티 값을 조회할 때 사용된다. 만약 값이 객체가 아니면, 해당 타입에 맞는 래퍼 객체를 사용해 프로퍼티 조회를 수행한다. 호출 시 다음 단계를 수행한다:

  1. O를 ? ToObject(V)로 한다.
  2. O.[[Get]](P, V)를 반환한다.

7.3.4 Set ( O, P, V, Throw )

추상 연산 Set은 인수 O(객체), P(프로퍼티 키), V(ECMAScript 언어 값), Throw(Boolean)을 받아, 특정 값을 포함하는 정상 완료 unused 또는 throw 완료를 반환한다. 이 연산은 객체의 특정 프로퍼티 값을 설정할 때 사용된다. V는 프로퍼티에 할당할 새 값이다. 호출 시 다음 단계를 수행한다:

  1. success를 ? O.[[Set]](P, V, O)로 한다.
  2. successfalse이고 Throwtrue이면 TypeError 예외를 throw한다.
  3. unused를 반환한다.

7.3.5 CreateDataProperty ( O, P, V )

추상 연산 CreateDataProperty는 인수 O(객체), P(프로퍼티 키), V(ECMAScript 언어 값)를 받아, 특정 값을 포함하는 정상 완료 Boolean 또는 throw 완료를 반환한다. 이 연산은 객체의 새로운 자기 프로퍼티를 생성하는 데 사용된다. 호출 시 다음 단계를 수행한다:

  1. newDesc를 PropertyDescriptor { [[Value]]: V, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }로 한다.
  2. O.[[DefineOwnProperty]](P, newDesc)를 반환한다.
참고

이 추상 연산은 ECMAScript 언어의 할당 연산자로 생성된 프로퍼티와 동일한 기본 속성으로 프로퍼티를 생성한다. 일반적으로 프로퍼티는 이미 존재하지 않는다. 만약 존재하고 설정 불가이거나 O가 확장 가능하지 않다면, [[DefineOwnProperty]]false를 반환한다.

7.3.6 CreateDataPropertyOrThrow ( O, P, V )

추상 연산 CreateDataPropertyOrThrow는 인수 O(객체), P(프로퍼티 키), V(ECMAScript 언어 값)를 받아, 특정 값을 포함하는 정상 완료 unused 또는 throw 완료를 반환한다. 이 연산은 객체의 새로운 자기 프로퍼티를 생성하는 데 사용된다. 요청된 프로퍼티 갱신을 수행할 수 없으면 TypeError 예외를 던진다. 호출 시 다음 단계를 수행한다:

  1. success를 ? CreateDataProperty(O, P, V)로 한다.
  2. successfalse이면 TypeError 예외를 throw한다.
  3. unused를 반환한다.
참고

이 추상 연산은 ECMAScript 언어의 할당 연산자로 생성된 프로퍼티와 동일한 기본 속성으로 프로퍼티를 생성한다. 일반적으로 프로퍼티는 이미 존재하지 않는다. 만약 존재하고 설정 불가이거나 O가 확장 가능하지 않다면, [[DefineOwnProperty]]false를 반환하고, 이 연산은 TypeError 예외를 던진다.

7.3.7 CreateNonEnumerableDataPropertyOrThrow ( O, P, V )

추상 연산 CreateNonEnumerableDataPropertyOrThrow는 인수 O(객체), P(프로퍼티 키), V(ECMAScript 언어 값)를 받아 unused를 반환한다. 이 연산은 일반 객체의 새로운 비열거형 자기 프로퍼티를 생성하는 데 사용된다. 호출 시 다음 단계를 수행한다:

  1. Assert: O는 비설정 불가 프로퍼티가 없는 일반적이고 확장 가능한 객체이다.
  2. newDesc를 PropertyDescriptor { [[Value]]: V, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }로 한다.
  3. DefinePropertyOrThrow(O, P, newDesc)를 수행한다.
  4. unused를 반환한다.
참고

이 추상 연산은 ECMAScript 언어의 할당 연산자로 생성된 프로퍼티와 동일한 기본 속성으로 프로퍼티를 생성하지만, 열거형이 아니다. 일반적으로 프로퍼티는 이미 존재하지 않는다. 만약 존재한다면 DefinePropertyOrThrow가 정상적으로 완료됨이 보장된다.

7.3.8 DefinePropertyOrThrow ( O, P, desc )

추상 연산 DefinePropertyOrThrow는 인수 O(객체), P(프로퍼티 키), desc(프로퍼티 디스크립터)를 받아, 특정 값을 포함하는 정상 완료 unused 또는 throw 완료를 반환한다. 이 연산은 객체의 [[DefineOwnProperty]] 내부 메서드를 호출하여, 요청된 프로퍼티 갱신을 수행할 수 없을 경우 TypeError 예외를 던진다. 호출 시 다음 단계를 수행한다:

  1. success를 ? O.[[DefineOwnProperty]](P, desc)로 한다.
  2. successfalse이면 TypeError 예외를 throw한다.
  3. unused를 반환한다.

7.3.9 DeletePropertyOrThrow ( O, P )

추상 연산 DeletePropertyOrThrow는 인수 O(객체), P(프로퍼티 키)를 받아, 특정 값을 포함하는 정상 완료 unused 또는 throw 완료를 반환한다. 이 연산은 객체의 특정 자기 프로퍼티를 제거하는 데 사용된다. 해당 프로퍼티가 설정 불가라면 예외를 던진다. 호출 시 다음 단계를 수행한다:

  1. success를 ? O.[[Delete]](P)로 한다.
  2. successfalse이면 TypeError 예외를 throw한다.
  3. unused를 반환한다.

7.3.10 GetMethod ( V, P )

추상 연산 GetMethod는 인수 V(ECMAScript 언어 값), P(프로퍼티 키)를 받아, 특정 값을 포함하는 정상 완료 함수 객체 또는 undefined, 혹은 throw 완료를 반환한다. 이 연산은 해당 프로퍼티의 값이 함수일 것으로 기대되는 ECMAScript 언어 값의 특정 프로퍼티 값을 가져오는 데 사용된다. 호출 시 다음 단계를 수행한다:

  1. func를 ? GetV(V, P)로 한다.
  2. funcundefined 또는 null이면 undefined를 반환한다.
  3. IsCallable(func)이 false이면 TypeError 예외를 throw한다.
  4. func를 반환한다.

7.3.11 HasProperty ( O, P )

추상 연산 HasProperty는 인수 O(객체), P(프로퍼티 키)를 받아, 특정 값을 포함하는 정상 완료 Boolean 또는 throw 완료를 반환한다. 이 연산은 객체에 지정된 프로퍼티 키의 프로퍼티가 존재하는지(자기 또는 상속 포함) 확인하는 데 사용된다. 호출 시 다음 단계를 수행한다:

  1. O.[[HasProperty]](P)를 반환한다.

7.3.12 HasOwnProperty ( O, P )

추상 연산 HasOwnProperty는 인수 O(객체), P(프로퍼티 키)를 받아, 특정 값을 포함하는 정상 완료 Boolean 또는 throw 완료를 반환한다. 이 연산은 객체에 지정된 프로퍼티 키의 자기 프로퍼티가 존재하는지 확인하는 데 사용된다. 호출 시 다음 단계를 수행한다:

  1. desc를 ? O.[[GetOwnProperty]](P)로 한다.
  2. descundefined이면 false를 반환한다.
  3. true를 반환한다.

7.3.13 Call ( F, V [ , argumentsList ] )

추상 연산 Call은 인수 F(ECMAScript 언어 값), V(ECMAScript 언어 값), 선택적 인수 argumentsList(ECMAScript 언어 값의 List)를 받아, 특정 값을 포함하는 정상 완료 ECMAScript 언어 값 또는 throw 완료를 반환한다. 이 연산은 함수 객체의 [[Call]] 내부 메서드를 호출하는 데 사용된다. F가 함수 객체이고, V[[Call]]this 값이며, argumentsList는 내부 메서드의 해당 인수로 전달된다. argumentsList가 없으면, 새로운 빈 List가 사용된다. 호출 시 다음 단계를 수행한다:

  1. argumentsList가 없으면, argumentsList를 새로운 빈 List로 설정한다.
  2. IsCallable(F)가 false이면 TypeError 예외를 throw한다.
  3. F.[[Call]](V, argumentsList)를 반환한다.

7.3.14 Construct ( F [ , argumentsList [ , newTarget ] ] )

추상 연산 Construct는 인수 F(생성자)와 선택적 인수 argumentsList(ListECMAScript 언어 값), newTarget(생성자)를 받아, 특정 값을 포함하는 정상 완료 객체 또는 throw 완료를 반환한다. 이 연산은 함수 객체[[Construct]] 내부 메서드를 호출하는 데 사용된다. argumentsListnewTarget는 내부 메서드의 해당 인수로 전달되는 값이다. argumentsList가 없으면 새로운 빈 List가 사용된다. newTarget가 없으면 F가 사용된다. 호출 시 다음 단계를 수행한다:

  1. newTarget가 없으면 newTargetF로 설정한다.
  2. argumentsList가 없으면 argumentsList를 새로운 빈 List로 설정한다.
  3. F.[[Construct]](argumentsList, newTarget)를 반환한다.
참고

newTarget가 없으면 이 연산은 new F(...argumentsList)와 같다.

7.3.15 SetIntegrityLevel ( O, level )

추상 연산 SetIntegrityLevel은 인수 O(객체), level(sealed 또는 frozen)를 받아, 특정 값을 포함하는 정상 완료 Boolean 또는 throw 완료를 반환한다. 이 연산은 객체의 자기 프로퍼티 집합을 고정하는 데 사용된다. 호출 시 다음 단계를 수행한다:

  1. status를 ? O.[[PreventExtensions]]()로 한다.
  2. statusfalse이면 false를 반환한다.
  3. keys를 ? O.[[OwnPropertyKeys]]()로 한다.
  4. levelsealed이면,
    1. keys의 각 요소 k에 대해, 다음을 수행한다:
      1. DefinePropertyOrThrow(O, k, PropertyDescriptor { [[Configurable]]: false })를 수행한다.
  5. 그 외의 경우,
    1. Assert: levelfrozen이다.
    2. keys의 각 요소 k에 대해, 다음을 수행한다:
      1. currentDesc를 ? O.[[GetOwnProperty]](k)로 한다.
      2. currentDescundefined가 아니면, 다음을 수행한다:
        1. IsAccessorDescriptor(currentDesc) 가 true이면,
          1. desc를 PropertyDescriptor { [[Configurable]]: false }로 한다.
        2. 그 외의 경우,
          1. desc를 PropertyDescriptor { [[Configurable]]: false, [[Writable]]: false }로 한다.
        3. DefinePropertyOrThrow(O, k, desc)를 수행한다.
  6. true를 반환한다.

7.3.16 TestIntegrityLevel ( O, level )

추상 연산 TestIntegrityLevel은 인수 O(객체), level(sealed 또는 frozen)를 받아, 특정 값을 포함하는 정상 완료 Boolean 또는 throw 완료를 반환한다. 이 연산은 객체의 자기 프로퍼티 집합이 고정되어 있는지 판단하는 데 사용된다. 호출 시 다음 단계를 수행한다:

  1. extensible를 ? IsExtensible(O)로 한다.
  2. extensibletrue이면 false를 반환한다.
  3. 참고: 객체가 확장 가능하면, 프로퍼티는 검사하지 않는다.
  4. keys를 ? O.[[OwnPropertyKeys]]()로 한다.
  5. keys의 각 요소 k에 대해, 다음을 수행한다:
    1. currentDesc를 ? O.[[GetOwnProperty]](k)로 한다.
    2. currentDescundefined가 아니면, 다음을 수행한다:
      1. currentDesc.[[Configurable]]true이면 false를 반환한다.
      2. levelfrozen이고 IsDataDescriptor(currentDesc) 가 true이면,
        1. currentDesc.[[Writable]]true이면 false를 반환한다.
  6. true를 반환한다.

7.3.17 CreateArrayFromList ( elements )

추상 연산 CreateArrayFromList는 인수 elements(ListECMAScript 언어 값)를 받아, 배열을 반환한다. 이 연산은 elements가 제공하는 요소로 구성된 배열을 생성하는 데 사용된다. 호출 시 다음 단계를 수행한다:

  1. array를 ! ArrayCreate(0)으로 한다.
  2. n을 0으로 한다.
  3. elements의 각 요소 e에 대해, 다음을 수행한다:
    1. CreateDataPropertyOrThrow(array, ! ToString(𝔽(n)), e)를 수행한다.
    2. nn + 1로 설정한다.
  4. array를 반환한다.

7.3.18 LengthOfArrayLike ( obj )

추상 연산 LengthOfArrayLike는 인수 obj(객체)를 받아, 정상 완료로 음이 아닌 정수 또는 throw 완료를 반환한다. 이 연산은 배열과 유사한 객체의 "length" 프로퍼티 값을 반환한다. 호출 시 다음 단계를 수행한다:

  1. (? ToLength(? Get(obj, "length")))를 반환한다.

배열과 유사한 객체란 이 연산이 정상 완료를 반환하는 모든 객체이다.

참고 1
일반적으로 배열과 유사한 객체는 정수 인덱스 이름을 가진 프로퍼티도 가진다. 하지만 이는 이 정의의 필수 조건이 아니다.
참고 2
배열과 문자열 객체는 배열과 유사한 객체의 예시이다.

7.3.19 CreateListFromArrayLike ( obj [ , validElementTypes ] )

추상 연산 CreateListFromArrayLike는 인수 obj(ECMAScript 언어 값)와 선택적 인수 validElementTypes(all 또는 property-key)를 받아, 정상 완료 List (요소는 ECMAScript 언어 값) 또는 throw 완료를 반환한다. 이 연산은 obj의 인덱스 프로퍼티로부터 제공되는 요소들로 구성된 List 값을 생성하는 데 사용된다. validElementTypes는 요소로 허용되는 값의 타입을 나타낸다. 호출 시 다음 단계를 수행한다:

  1. validElementTypes가 주어지지 않으면, validElementTypesall로 설정한다.
  2. obj객체가 아니면 TypeError 예외를 throw한다.
  3. len을 ? LengthOfArrayLike(obj)로 한다.
  4. list를 새로운 빈 List로 한다.
  5. index를 0으로 한다.
  6. index < len 동안 반복한다,
    1. indexName을 ! ToString(𝔽(index))로 한다.
    2. next를 ? Get(obj, indexName)로 한다.
    3. validElementTypesproperty-key이고 next프로퍼티 키가 아니면 TypeError 예외를 throw한다.
    4. nextlist에 추가한다.
    5. indexindex + 1로 한다.
  7. list를 반환한다.

7.3.20 Invoke ( V, P [ , argumentsList ] )

추상 연산 Invoke는 인수 V(ECMAScript 언어 값), P(프로퍼티 키), 선택적 인수 argumentsList(ECMAScript 언어 값의 List)를 받아, 정상 완료 ECMAScript 언어 값 또는 throw 완료를 반환한다. 이 연산은 ECMAScript 언어 값의 메서드 프로퍼티를 호출하는 데 사용된다. V는 프로퍼티 조회 지점이자 호출 시 this 값으로 사용된다. argumentsList는 메서드에 전달되는 인자 값들의 목록이다. argumentsList가 없다면 새로운 빈 List가 사용된다. 호출 시 다음 단계를 수행한다:

  1. argumentsList가 없으면 argumentsList를 새로운 빈 List로 한다.
  2. func를 ? GetV(V, P)로 한다.
  3. Call(func, V, argumentsList)를 반환한다.

7.3.21 OrdinaryHasInstance ( C, O )

추상 연산 OrdinaryHasInstance는 인수 C(ECMAScript 언어 값), O(ECMAScript 언어 값)를 받아, 정상 완료 Boolean 또는 throw 완료를 반환한다. 이 연산은 OC가 제공하는 인스턴스 객체 상속 경로에서 상속받는지의 기본 알고리즘을 구현한다. 호출 시 다음 단계를 수행한다:

  1. IsCallable(C)가 false이면 false를 반환한다.
  2. C[[BoundTargetFunction]] 내부 슬롯이 있으면,
    1. BCC.[[BoundTargetFunction]]로 한다.
    2. InstanceofOperator(O, BC)를 반환한다.
  3. O객체가 아니면 false를 반환한다.
  4. P를 ? Get(C, "prototype")로 한다.
  5. P객체가 아니면 TypeError 예외를 throw한다.
  6. 반복한다,
    1. O를 ? O.[[GetPrototypeOf]]()로 한다.
    2. Onull이면 false를 반환한다.
    3. SameValue(P, O)가 true이면 true를 반환한다.

7.3.22 SpeciesConstructor ( O, defaultConstructor )

추상 연산 SpeciesConstructor는 인수 O(객체), defaultConstructor(생성자)를 받아, 정상 완료생성자 또는 throw 완료를 반환한다. 이 연산은 O로부터 파생된 새 객체를 생성하는 데 사용할 생성자를 검색하는 데 사용된다. defaultConstructorO에서 생성자 %Symbol.species% 프로퍼티를 찾을 수 없을 때 사용된다. 호출 시 다음 단계를 수행한다:

  1. C를 ? Get(O, "constructor")로 한다.
  2. Cundefined이면 defaultConstructor를 반환한다.
  3. C객체가 아니면 TypeError 예외를 throw한다.
  4. S를 ? Get(C, %Symbol.species%)로 한다.
  5. Sundefined 또는 null이면 defaultConstructor를 반환한다.
  6. IsConstructor(S)가 true이면 S를 반환한다.
  7. TypeError 예외를 throw한다.

7.3.23 EnumerableOwnProperties ( O, kind )

추상 연산 EnumerableOwnProperties는 인수 O(객체), kind(key, value, key+value)를 받아, 정상 완료 List (ECMAScript 언어 값) 또는 throw 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. ownKeys를 ? O.[[OwnPropertyKeys]]()로 한다.
  2. results를 새로운 빈 List로 한다.
  3. ownKeys의 각 요소 key에 대해, 다음을 수행한다:
    1. key문자열이면, 다음을 수행한다:
      1. desc를 ? O.[[GetOwnProperty]](key)로 한다.
      2. descundefined가 아니고 desc.[[Enumerable]]true이면, 다음을 수행한다:
        1. kindkey이면,
          1. keyresults에 추가한다.
        2. 그 외의 경우,
          1. value를 ? Get(O, key)로 한다.
          2. kindvalue이면,
            1. valueresults에 추가한다.
          3. 그 외의 경우,
            1. Assert: kindkey+value임을 보장한다.
            2. entryCreateArrayFromListkey, value »)로 한다.
            3. entryresults에 추가한다.
  4. results를 반환한다.

7.3.24 GetFunctionRealm ( obj )

추상 연산 GetFunctionRealm은 인수 obj(함수 객체)를 받아, 정상 완료 Realm Record 또는 throw 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. obj[[Realm]] 내부 슬롯이 있으면,
    1. obj.[[Realm]]을 반환한다.
  2. objbound function exotic object이면,
    1. boundTargetFunctionobj.[[BoundTargetFunction]]로 한다.
    2. GetFunctionRealm(boundTargetFunction)을 반환한다.
  3. objProxy exotic object이면,
    1. ValidateNonRevokedProxy(obj)를 수행한다.
    2. proxyTargetobj.[[ProxyTarget]]로 한다.
    3. Assert: proxyTarget함수 객체임을 보장한다.
    4. GetFunctionRealm(proxyTarget)을 반환한다.
  4. 현재 Realm Record를 반환한다.
참고

4 단계는 obj[[Realm]] 내부 슬롯이 없는 비표준 함수 특수 객체일 때만 도달한다.

7.3.25 CopyDataProperties ( target, source, excludedItems )

추상 연산 CopyDataProperties는 인수 target(객체), source(ECMAScript 언어 값), excludedItems(프로퍼티 키의 List)를 받아, 정상 완료 unused 또는 throw 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. sourceundefined 또는 null이면, unused를 반환한다.
  2. from을 ! ToObject(source)로 한다.
  3. keys를 ? from.[[OwnPropertyKeys]]()로 한다.
  4. keys의 각 요소 nextKey에 대해, 다음을 수행한다:
    1. excludedfalse로 한다.
    2. excludedItems의 각 요소 e에 대해, 다음을 수행한다:
      1. SameValue(e, nextKey)가 true이면,
        1. excludedtrue로 설정한다.
    3. excludedfalse이면, 다음을 수행한다:
      1. desc를 ? from.[[GetOwnProperty]](nextKey)로 한다.
      2. descundefined가 아니고 desc.[[Enumerable]]true이면, 다음을 수행한다:
        1. propValue를 ? Get(from, nextKey)로 한다.
        2. CreateDataPropertyOrThrow(target, nextKey, propValue)를 수행한다.
  5. unused를 반환한다.
참고

여기서 전달된 target은 항상 새로 생성된 객체이므로, 오류가 발생해도 직접 접근할 수 없다.

7.3.26 PrivateElementFind ( O, P )

추상 연산 PrivateElementFind는 인수 O(객체), P(프라이빗 이름)를 받아, PrivateElement 또는 empty를 반환한다. 호출 시 다음 단계를 수행한다:

  1. O.[[PrivateElements]]PrivateElement pe가 존재하고, pe.[[Key]]P와 같으면,
    1. pe를 반환한다.
  2. empty를 반환한다.

7.3.27 PrivateFieldAdd ( O, P, value )

추상 연산 PrivateFieldAdd는 인수 O(객체), P(프라이빗 이름), value(ECMAScript 언어 값)를 받아, 정상 완료 unused 또는 throw 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. 호스트가 웹 브라우저이면,
    1. HostEnsureCanAddPrivateElement(O)를 수행한다.
  2. entryPrivateElementFind(O, P)로 한다.
  3. entryempty가 아니면 TypeError 예외를 throw한다.
  4. PrivateElement { [[Key]]: P, [[Kind]]: field, [[Value]]: value }를 O.[[PrivateElements]]에 추가한다.
  5. unused를 반환한다.

7.3.28 PrivateMethodOrAccessorAdd ( O, method )

추상 연산 PrivateMethodOrAccessorAdd는 인수 O(객체), method(PrivateElement)를 받아, 정상 완료 unused 또는 throw 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. Assert: method.[[Kind]]method 또는 accessor임을 보장한다.
  2. 호스트가 웹 브라우저이면,
    1. HostEnsureCanAddPrivateElement(O)를 수행한다.
  3. entryPrivateElementFind(O, method.[[Key]])로 한다.
  4. entryempty가 아니면 TypeError 예외를 throw한다.
  5. methodO.[[PrivateElements]]에 추가한다.
  6. unused를 반환한다.
참고

프라이빗 메서드와 접근자의 값은 인스턴스 간에 공유된다. 이 연산은 메서드나 접근자의 새 복사본을 생성하지 않는다.

7.3.29 HostEnsureCanAddPrivateElement ( O )

호스트 정의 추상 연산 HostEnsureCanAddPrivateElement는 인수 O(객체)를 받아, 정상 완료 unused 또는 throw 완료를 반환한다. 이 연산은 호스트 환경이 특정 호스트 정의 특수 객체에 프라이빗 요소 추가를 방지할 수 있도록 한다.

HostEnsureCanAddPrivateElement의 구현은 다음 요구사항을 따라야 한다:

HostEnsureCanAddPrivateElement의 기본 구현은 NormalCompletion(unused)을 반환하는 것이다.

이 추상 연산은 ECMAScript 호스트가 웹 브라우저인 경우에만 호출된다.

7.3.30 PrivateGet ( O, P )

추상 연산 PrivateGet은 인수 O(객체), P(프라이빗 이름)를 받아, 정상 완료 ECMAScript 언어 값 또는 throw 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. entryPrivateElementFind(O, P)로 한다.
  2. entryempty이면 TypeError 예외를 throw한다.
  3. entry.[[Kind]]field 또는 method이면,
    1. entry.[[Value]]를 반환한다.
  4. Assert: entry.[[Kind]]accessor임을 보장한다.
  5. entry.[[Get]]undefined이면 TypeError 예외를 throw한다.
  6. getterentry.[[Get]]로 한다.
  7. Call(getter, O)를 반환한다.

7.3.31 PrivateSet ( O, P, value )

추상 연산 PrivateSet은 인수 O(객체), P(프라이빗 이름), value(ECMAScript 언어 값)를 받아, 정상 완료 unused 또는 throw 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. entryPrivateElementFind(O, P)로 한다.
  2. entryempty이면 TypeError 예외를 throw한다.
  3. entry.[[Kind]]field이면,
    1. entry.[[Value]]value를 할당한다.
  4. 그 외 entry.[[Kind]]method이면,
    1. TypeError 예외를 throw한다.
  5. 그 외의 경우,
    1. Assert: entry.[[Kind]]accessor임을 보장한다.
    2. entry.[[Set]]undefined이면 TypeError 예외를 throw한다.
    3. setterentry.[[Set]]로 한다.
    4. Call(setter, O, « value » )를 수행한다.
  6. unused를 반환한다.

7.3.32 DefineField ( receiver, fieldRecord )

추상 연산 DefineField는 인수 receiver(객체), fieldRecord(ClassFieldDefinition Record)를 받아, 정상 완료 unused 또는 throw 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. fieldNamefieldRecord.[[Name]]로 한다.
  2. initializerfieldRecord.[[Initializer]]로 한다.
  3. initializerempty가 아니면,
    1. initValue를 ? Call(initializer, receiver)로 한다.
  4. 그 외의 경우,
    1. initValueundefined로 한다.
  5. fieldName프라이빗 이름이면,
    1. PrivateFieldAdd(receiver, fieldName, initValue)를 수행한다.
  6. 그 외의 경우,
    1. Assert: fieldName프로퍼티 키임을 보장한다.
    2. CreateDataPropertyOrThrow(receiver, fieldName, initValue)를 수행한다.
  7. unused를 반환한다.

7.3.33 InitializeInstanceElements ( O, constructor )

추상 연산 InitializeInstanceElements는 인수 O(객체), constructor(ECMAScript 함수 객체)를 받아, 정상 완료 unused 또는 throw 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. methodsconstructor.[[PrivateMethods]]로 한다.
  2. methods의 각 PrivateElement method에 대해, 다음을 수행한다:
    1. PrivateMethodOrAccessorAdd(O, method)를 수행한다.
  3. fieldsconstructor.[[Fields]]로 한다.
  4. fields의 각 요소 fieldRecord에 대해, 다음을 수행한다:
    1. DefineField(O, fieldRecord)를 수행한다.
  5. unused를 반환한다.

7.3.34 AddValueToKeyedGroup ( groups, key, value )

추상 연산 AddValueToKeyedGroup은 인수 groups(ListRecord이며, 필드 [[Key]](ECMAScript 언어 값)와 [[Elements]](ListECMAScript 언어 값)), key(ECMAScript 언어 값), value(ECMAScript 언어 값)를 받아 unused를 반환한다. 호출 시 다음 단계를 수행한다:

  1. groups의 각 Record { [[Key]], [[Elements]] } g에 대해, 다음을 수행한다:
    1. SameValue(g.[[Key]], key)가 true이면,
      1. Assert: groups의 정확히 하나의 요소만 이 조건을 만족한다.
      2. valueg.[[Elements]]에 추가한다.
      3. unused를 반환한다.
  2. groupRecord { [[Key]]: key, [[Elements]]: « value » }로 한다.
  3. groupgroups에 추가한다.
  4. unused를 반환한다.

7.3.35 GroupBy ( items, callback, keyCoercion )

추상 연산 GroupBy는 인수 items(ECMAScript 언어 값), callback(ECMAScript 언어 값), keyCoercion(property 또는 collection)를 받아, 정상 완료 List (Record이며, 필드 [[Key]](ECMAScript 언어 값) 및 [[Elements]](ListECMAScript 언어 값)), 또는 throw 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. RequireObjectCoercible(items)를 수행한다.
  2. IsCallable(callback)이 false이면 TypeError 예외를 throw한다.
  3. groups를 새로운 빈 List로 한다.
  4. iteratorRecord를 ? GetIterator(items, sync)로 한다.
  5. k를 0으로 한다.
  6. 반복한다,
    1. k ≥ 253 - 1이면,
      1. errorThrowCompletion(새로 생성된 TypeError 객체)로 한다.
      2. IteratorClose(iteratorRecord, error)를 반환한다.
    2. next를 ? IteratorStepValue(iteratorRecord)로 한다.
    3. nextdone이면,
      1. groups를 반환한다.
    4. valuenext로 한다.
    5. keyCompletion(Call(callback, undefined, « value, 𝔽(k) »))로 한다.
    6. IfAbruptCloseIterator(key, iteratorRecord)를 수행한다.
    7. keyCoercionproperty이면,
      1. keyCompletion(ToPropertyKey(key))로 설정한다.
      2. IfAbruptCloseIterator(key, iteratorRecord)를 수행한다.
    8. 그 외의 경우,
      1. Assert: keyCoercioncollection임을 보장한다.
      2. keyCanonicalizeKeyedCollectionKey(key)로 설정한다.
    9. AddValueToKeyedGroup(groups, key, value)를 수행한다.
    10. kk + 1로 설정한다.

7.3.36 SetterThatIgnoresPrototypeProperties ( thisValue, home, p, v )

추상 연산 SetterThatIgnoresPrototypeProperties는 인수 thisValue(ECMAScript 언어 값), home(객체), p(프로퍼티 키), v(ECMAScript 언어 값)를 받아, 정상 완료 unused 또는 throw 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. thisValue객체가 아니면,
    1. TypeError 예외를 throw한다.
  2. SameValue(thisValue, home)가 true이면,
    1. 참고: 여기서 예외를 던지는 것은 home 객체의 strict mode 코드에서 쓰기 불가 데이터 프로퍼티에 대입하는 효과를 모방한다.
    2. TypeError 예외를 throw한다.
  3. desc를 ? thisValue.[[GetOwnProperty]](p)로 한다.
  4. descundefined이면,
    1. CreateDataPropertyOrThrow(thisValue, p, v)를 수행한다.
  5. 그 외의 경우,
    1. Set(thisValue, p, v, true)를 수행한다.
  6. unused를 반환한다.

7.4 반복자 객체에 대한 연산

공통 반복 인터페이스(27.1 참조).

7.4.1 반복자 레코드

반복자 레코드Record 값으로, 반복자 또는 비동기 반복자next 메서드를 캡슐화하는 데 사용된다.

반복자 레코드는 표 15에 나열된 필드를 가진다.

표 15: 반복자 레코드 필드
필드 이름 의미
[[Iterator]] 객체 반복자 인터페이스 또는 비동기 반복자 인터페이스를 따르는 객체.
[[NextMethod]] ECMAScript 언어 값 [[Iterator]] 객체의 next 메서드.
[[Done]] 불린 반복자가 완료되었거나 닫혔는지 여부.

7.4.2 GetIteratorDirect ( obj )

추상 연산 GetIteratorDirect는 인수 obj(객체)를 받아, 정상 완료반복자 레코드 또는 throw 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. nextMethod를 ? Get(obj, "next")로 한다.
  2. iteratorRecord반복자 레코드 { [[Iterator]]: obj, [[NextMethod]]: nextMethod, [[Done]]: false }로 한다.
  3. iteratorRecord를 반환한다.

7.4.3 GetIteratorFromMethod ( obj, method )

추상 연산 GetIteratorFromMethod는 인수 obj(ECMAScript 언어 값), method(함수 객체)를 받아, 정상 완료반복자 레코드 또는 throw 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. iterator를 ? Call(method, obj)로 한다.
  2. iterator객체가 아니면 TypeError 예외를 throw한다.
  3. GetIteratorDirect(iterator)를 반환한다.

7.4.4 GetIterator ( obj, kind )

추상 연산 GetIterator는 인수 obj(ECMAScript 언어 값), kind(sync 또는 async)를 받아, 정상 완료반복자 레코드 또는 throw 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. kindasync이면,
    1. method를 ? GetMethod(obj, %Symbol.asyncIterator%)로 한다.
    2. methodundefined이면,
      1. syncMethod를 ? GetMethod(obj, %Symbol.iterator%)로 한다.
      2. syncMethodundefined이면 TypeError 예외를 throw한다.
      3. syncIteratorRecord를 ? GetIteratorFromMethod(obj, syncMethod)로 한다.
      4. CreateAsyncFromSyncIterator(syncIteratorRecord)를 반환한다.
  2. 그 외의 경우,
    1. method를 ? GetMethod(obj, %Symbol.iterator%)로 한다.
  3. methodundefined이면 TypeError 예외를 throw한다.
  4. GetIteratorFromMethod(obj, method)를 반환한다.

7.4.5 GetIteratorFlattenable ( obj, primitiveHandling )

추상 연산 GetIteratorFlattenable는 인수 obj(ECMAScript 언어 값), primitiveHandling(iterate-string-primitives 또는 reject-primitives)를 받아, 정상 완료반복자 레코드 또는 throw 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. obj객체가 아니면,
    1. primitiveHandlingreject-primitives이면 TypeError 예외를 throw한다.
    2. Assert: primitiveHandlingiterate-string-primitives임을 보장한다.
    3. obj문자열이 아니면, TypeError 예외를 throw한다.
  2. method를 ? GetMethod(obj, %Symbol.iterator%)로 한다.
  3. methodundefined이면,
    1. iteratorobj로 한다.
  4. 그 외의 경우,
    1. iterator를 ? Call(method, obj)로 한다.
  5. iterator객체가 아니면 TypeError 예외를 throw한다.
  6. GetIteratorDirect(iterator)를 반환한다.

7.4.6 IteratorNext ( iteratorRecord [ , value ] )

추상 연산 IteratorNext는 인수 iteratorRecord(반복자 레코드), 선택적 인수 value(ECMAScript 언어 값)를 받아, 정상 완료 객체 또는 throw 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. value가 없으면,
    1. resultCompletion(Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]]))로 한다.
  2. 그 외의 경우,
    1. resultCompletion(Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]], « value »))로 한다.
  3. resultthrow 완료이면,
    1. iteratorRecord.[[Done]]true로 설정한다.
    2. result를 반환한다.
  4. result를 ! result로 설정한다.
  5. result객체가 아니면,
    1. iteratorRecord.[[Done]]true로 설정한다.
    2. TypeError 예외를 throw한다.
  6. result를 반환한다.

7.4.7 IteratorComplete ( iteratorResult )

추상 연산 IteratorComplete는 인수 iteratorResult(객체)를 받아, 정상 완료 불린 또는 throw 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. ToBoolean(? Get(iteratorResult, "done"))를 반환한다.

7.4.8 IteratorValue ( iteratorResult )

추상 연산 IteratorValue는 인수 iteratorResult(객체)를 받아, 정상 완료 ECMAScript 언어 값 또는 throw 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. Get(iteratorResult, "value")를 반환한다.

7.4.9 IteratorStep ( iteratorRecord )

추상 연산 IteratorStep은 인수 iteratorRecord(반복자 레코드)를 받아, 정상 완료 객체 또는 done, 또는 throw 완료를 반환한다. iteratorRecord.[[Iterator]]iteratorRecord.[[NextMethod]]를 호출하여 다음 값을 요청하고, 끝에 도달하면 done를 반환하며, 다음 값이 있으면 IteratorResult 객체를 반환한다. 호출 시 다음 단계를 수행한다:

  1. result를 ? IteratorNext(iteratorRecord)로 한다.
  2. doneCompletion(IteratorComplete(result))로 한다.
  3. donethrow 완료이면,
    1. iteratorRecord.[[Done]]true로 설정한다.
    2. done을 반환한다.
  4. done을 ! done으로 설정한다.
  5. donetrue이면,
    1. iteratorRecord.[[Done]]true로 설정한다.
    2. done를 반환한다.
  6. result를 반환한다.

7.4.10 IteratorStepValue ( iteratorRecord )

추상 연산 IteratorStepValue는 인수 iteratorRecord(반복자 레코드)를 받아, 정상 완료 ECMAScript 언어 값 또는 done, 또는 throw 완료를 반환한다. iteratorRecord.[[Iterator]]iteratorRecord.[[NextMethod]]를 호출하여 다음 값을 요청하고, 끝에 도달하면 done를 반환하며, 다음 값이 있으면 그 값을 반환한다. 호출 시 다음 단계를 수행한다:

  1. result를 ? IteratorStep(iteratorRecord)로 한다.
  2. resultdone이면,
    1. done를 반환한다.
  3. valueCompletion(IteratorValue(result))로 한다.
  4. valuethrow 완료이면,
    1. iteratorRecord.[[Done]]true로 설정한다.
  5. value를 반환한다.

7.4.11 IteratorClose ( iteratorRecord, completion )

추상 연산 IteratorClose는 인수 iteratorRecord(반복자 레코드), completion(Completion Record)를 받아, Completion Record를 반환한다. 이는 반복자가 완료 상태가 되었을 때 수행해야 할 동작을 알리는 데 사용된다. 호출 시 다음 단계를 수행한다:

  1. Assert: iteratorRecord.[[Iterator]]객체임을 보장한다.
  2. iteratoriteratorRecord.[[Iterator]]로 한다.
  3. innerResultCompletion(GetMethod(iterator, "return"))로 한다.
  4. innerResult정상 완료이면,
    1. returninnerResult.[[Value]]로 한다.
    2. returnundefined이면 ? completion을 반환한다.
    3. innerResultCompletion(Call(return, iterator))로 설정한다.
  5. completionthrow 완료이면 ? completion을 반환한다.
  6. innerResultthrow 완료이면 ? innerResult를 반환한다.
  7. innerResult.[[Value]]객체가 아니면 TypeError 예외를 throw한다.
  8. completion을 반환한다.

7.4.12 IfAbruptCloseIterator ( value, iteratorRecord )

IfAbruptCloseIterator는 반복자 레코드를 사용하는 알고리즘 단계 시퀀스의 약식 표현이다. 다음과 같은 알고리즘 단계는:

  1. IfAbruptCloseIterator(value, iteratorRecord).

다음과 동일하다:

  1. Assert: valueCompletion Record이다.
  2. valueabrupt 완료이면, ? IteratorClose(iteratorRecord, value)를 반환한다.
  3. 그 외의 경우, value를 ! value로 설정한다.

7.4.13 AsyncIteratorClose ( iteratorRecord, completion )

추상 연산 AsyncIteratorClose는 인수 iteratorRecord(반복자 레코드), completion(Completion Record)를 받아, Completion Record를 반환한다. 이는 비동기 반복자가 완료 상태가 되었을 때 수행해야 할 동작을 알리는 데 사용된다. 호출 시 다음 단계를 수행한다:

  1. Assert: iteratorRecord.[[Iterator]]객체임을 보장한다.
  2. iteratoriteratorRecord.[[Iterator]]로 한다.
  3. innerResultCompletion(GetMethod(iterator, "return"))로 한다.
  4. innerResult정상 완료이면,
    1. returninnerResult.[[Value]]로 한다.
    2. returnundefined이면 ? completion을 반환한다.
    3. innerResultCompletion(Call(return, iterator))로 설정한다.
    4. innerResult정상 완료이면, innerResultCompletion(Await(innerResult.[[Value]]))로 설정한다.
  5. completionthrow 완료이면 ? completion을 반환한다.
  6. innerResultthrow 완료이면 ? innerResult를 반환한다.
  7. innerResult.[[Value]]객체가 아니면 TypeError 예외를 throw한다.
  8. completion을 반환한다.

7.4.14 CreateIteratorResultObject ( value, done )

추상 연산 CreateIteratorResultObject는 인수 value(ECMAScript 언어 값), done(불린)을 받아, IteratorResult 인터페이스를 따르는 객체를 반환한다. 호출 시 다음 단계를 수행한다:

  1. objOrdinaryObjectCreate(%Object.prototype%)로 한다.
  2. CreateDataPropertyOrThrow(obj, "value", value)를 수행한다.
  3. CreateDataPropertyOrThrow(obj, "done", done)를 수행한다.
  4. obj를 반환한다.

7.4.15 CreateListIteratorRecord ( list )

추상 연산 CreateListIteratorRecord는 인수 list(ECMAScript 언어 값의 List)를 받아, 반복자 레코드를 반환한다. 이 연산은 [[NextMethod]]list의 요소를 차례로 반환하는 반복자 레코드를 생성한다. 호출 시 다음 단계를 수행한다:

  1. closure를 인수가 없고 list를 캡처하는 새로운 Abstract Closure로 한다. 호출 시 다음 단계를 수행한다:
    1. list의 각 요소 E에 대해, 다음을 수행한다:
      1. GeneratorYield(CreateIteratorResultObject(E, false))를 수행한다.
    2. NormalCompletion(undefined)을 반환한다.
  2. iteratorCreateIteratorFromClosure(closure, empty, %Iterator.prototype%)로 한다.
  3. 반복자 레코드 { [[Iterator]]: iterator, [[NextMethod]]: %GeneratorPrototype.next%, [[Done]]: false }를 반환한다.
참고

리스트 반복자 객체는 ECMAScript 코드에서 직접 접근할 수 없다.

7.4.16 IteratorToList ( iteratorRecord )

추상 연산 IteratorToList는 인수 iteratorRecord(반복자 레코드)를 받아, 정상 완료 ECMAScript 언어 값의 List 또는 throw 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. values를 새로운 빈 List로 한다.
  2. 반복한다,
    1. next를 ? IteratorStepValue(iteratorRecord)로 한다.
    2. nextdone이면,
      1. values를 반환한다.
    3. nextvalues에 추가한다.

8 구문 지시 연산

이 절에 정의된 것 외에도, 특수화된 구문 지시 연산이 이 명세 전반에 걸쳐 정의되어 있다.

8.1 런타임 의미론: 평가

구문 지시 연산 Evaluation은 인수를 받지 않고 Completion Record를 반환한다.

참고
이 연산의 정의는 본 명세의 "ECMAScript 언어" 절들에 분산되어 있다. 각 정의는 해당 생성 규칙의 정의 위치 뒤에 나타난다.

8.2 스코프 분석

8.2.1 정적 의미론: BoundNames

구문 지시 연산 BoundNames는 인수를 받지 않고 문자열의 List를 반환한다.

참고

"*default*"는 이 명세 내에서, 별도의 이름이 없는 모듈의 기본 내보내기(default export)에 대한 합성 이름으로 사용된다. 해당 이름으로 모듈의 [[Environment]]에 항목이 생성되고, 해당 값이 보관된다. ResolveExport ( exportName [ , resolveSet ] )를 호출해 "default"라는 내보내기를 해석하면, [[BindingName]]"*default*"ResolvedBinding Record를 반환하게 되며, 이는 모듈의 [[Environment]]에서 위에서 언급한 값으로 해석된다. 이는 명세의 편의를 위해서만 이루어지며, 익명 기본 내보내기 또한 다른 내보내기와 동일하게 해석할 수 있도록 한다. 이 "*default*" 문자열은 ECMAScript 코드나 모듈 연결 알고리즘에서는 접근할 수 없다.

이는 다음 생성 규칙들에 대해 분할적으로 정의된다:

BindingIdentifier : Identifier
  1. 리스트의 유일한 요소가 StringValueIdentifier를 반환한다.
BindingIdentifier : yield
  1. « "yield" »를 반환한다.
BindingIdentifier : await
  1. « "await" »를 반환한다.
LexicalDeclaration : LetOrConst BindingList ;
  1. BoundNames of BindingList를 반환한다.
BindingList : BindingList , LexicalBinding
  1. names1BoundNames of BindingList로 한다.
  2. names2BoundNames of LexicalBinding로 한다.
  3. list-concatenation of names1names2를 반환한다.
LexicalBinding : BindingIdentifier Initializeropt
  1. BoundNames of BindingIdentifier를 반환한다.
LexicalBinding : BindingPattern Initializer
  1. BoundNames of BindingPattern를 반환한다.
VariableDeclarationList : VariableDeclarationList , VariableDeclaration
  1. names1BoundNames of VariableDeclarationList로 한다.
  2. names2BoundNames of VariableDeclaration로 한다.
  3. list-concatenation of names1names2를 반환한다.
VariableDeclaration : BindingIdentifier Initializeropt
  1. BoundNames of BindingIdentifier를 반환한다.
VariableDeclaration : BindingPattern Initializer
  1. BoundNames of BindingPattern를 반환한다.
ObjectBindingPattern : { }
  1. 새로운 빈 리스트를 반환한다.
ObjectBindingPattern : { BindingPropertyList , BindingRestProperty }
  1. names1BoundNames of BindingPropertyList로 한다.
  2. names2BoundNames of BindingRestProperty로 한다.
  3. list-concatenation of names1names2를 반환한다.
ArrayBindingPattern : [ Elisionopt ]
  1. 새로운 빈 리스트를 반환한다.
ArrayBindingPattern : [ Elisionopt BindingRestElement ]
  1. BoundNames of BindingRestElement를 반환한다.
ArrayBindingPattern : [ BindingElementList , Elisionopt ]
  1. BoundNames of BindingElementList를 반환한다.
ArrayBindingPattern : [ BindingElementList , Elisionopt BindingRestElement ]
  1. names1BoundNames of BindingElementList로 한다.
  2. names2BoundNames of BindingRestElement로 한다.
  3. list-concatenation of names1names2를 반환한다.
BindingPropertyList : BindingPropertyList , BindingProperty
  1. names1BoundNames of BindingPropertyList로 한다.
  2. names2BoundNames of BindingProperty로 한다.
  3. list-concatenation of names1names2를 반환한다.
BindingElementList : BindingElementList , BindingElisionElement
  1. names1BoundNames of BindingElementList로 한다.
  2. names2BoundNames of BindingElisionElement로 한다.
  3. list-concatenation of names1names2를 반환한다.
BindingElisionElement : Elisionopt BindingElement
  1. BoundNames of BindingElement를 반환한다.
BindingProperty : PropertyName : BindingElement
  1. BoundNames of BindingElement를 반환한다.
SingleNameBinding : BindingIdentifier Initializeropt
  1. BoundNames of BindingIdentifier를 반환한다.
BindingElement : BindingPattern Initializeropt
  1. BoundNames of BindingPattern를 반환한다.
ForDeclaration : LetOrConst ForBinding
  1. BoundNames of ForBinding를 반환한다.
FunctionDeclaration : function BindingIdentifier ( FormalParameters ) { FunctionBody }
  1. BoundNames of BindingIdentifier를 반환한다.
FunctionDeclaration : function ( FormalParameters ) { FunctionBody }
  1. « "*default*" »를 반환한다.
FormalParameters : [empty]
  1. 새로운 빈 리스트를 반환한다.
FormalParameters : FormalParameterList , FunctionRestParameter
  1. names1BoundNames of FormalParameterList로 한다.
  2. names2BoundNames of FunctionRestParameter로 한다.
  3. list-concatenation of names1names2를 반환한다.
FormalParameterList : FormalParameterList , FormalParameter
  1. names1BoundNames of FormalParameterList로 한다.
  2. names2BoundNames of FormalParameter로 한다.
  3. list-concatenation of names1names2를 반환한다.
ArrowParameters : CoverParenthesizedExpressionAndArrowParameterList
  1. formalsArrowFormalParameters로 한다. 이 CoverParenthesizedExpressionAndArrowParameterListcovered한 것이다.
  2. BoundNames of formals를 반환한다.
GeneratorDeclaration : function * BindingIdentifier ( FormalParameters ) { GeneratorBody }
  1. BoundNames of BindingIdentifier를 반환한다.
GeneratorDeclaration : function * ( FormalParameters ) { GeneratorBody }
  1. « "*default*" »를 반환한다.
AsyncGeneratorDeclaration : async function * BindingIdentifier ( FormalParameters ) { AsyncGeneratorBody }
  1. BoundNames of BindingIdentifier를 반환한다.
AsyncGeneratorDeclaration : async function * ( FormalParameters ) { AsyncGeneratorBody }
  1. « "*default*" »를 반환한다.
ClassDeclaration : class BindingIdentifier ClassTail
  1. BoundNames of BindingIdentifier를 반환한다.
ClassDeclaration : class ClassTail
  1. « "*default*" »를 반환한다.
AsyncFunctionDeclaration : async function BindingIdentifier ( FormalParameters ) { AsyncFunctionBody }
  1. BoundNames of BindingIdentifier를 반환한다.
AsyncFunctionDeclaration : async function ( FormalParameters ) { AsyncFunctionBody }
  1. « "*default*" »를 반환한다.
CoverCallExpressionAndAsyncArrowHead : MemberExpression Arguments
  1. headAsyncArrowHead로 한다. 이 CoverCallExpressionAndAsyncArrowParameterListcovered한 것이다.
  2. BoundNames of head를 반환한다.
ImportDeclaration : import ImportClause FromClause WithClauseopt ;
  1. BoundNames of ImportClause를 반환한다.
ImportDeclaration : import ModuleSpecifier WithClauseopt ;
  1. 새로운 빈 리스트를 반환한다.
ImportClause : ImportedDefaultBinding , NameSpaceImport
  1. names1BoundNames of ImportedDefaultBinding로 한다.
  2. names2BoundNames of NameSpaceImport로 한다.
  3. list-concatenation of names1names2를 반환한다.
ImportClause : ImportedDefaultBinding , NamedImports
  1. names1BoundNames of ImportedDefaultBinding로 한다.
  2. names2BoundNames of NamedImports로 한다.
  3. list-concatenation of names1names2를 반환한다.
NamedImports : { }
  1. 새로운 빈 리스트를 반환한다.
ImportsList : ImportsList , ImportSpecifier
  1. names1BoundNames of ImportsList로 한다.
  2. names2BoundNames of ImportSpecifier로 한다.
  3. list-concatenation of names1names2를 반환한다.
ImportSpecifier : ModuleExportName as ImportedBinding
  1. BoundNames of ImportedBinding를 반환한다.
ExportDeclaration : export ExportFromClause FromClause WithClauseopt ; export NamedExports ;
  1. 새로운 빈 리스트를 반환한다.
ExportDeclaration : export VariableStatement
  1. BoundNames of VariableStatement를 반환한다.
ExportDeclaration : export Declaration
  1. BoundNames of Declaration를 반환한다.
ExportDeclaration : export default HoistableDeclaration
  1. declarationNamesBoundNames of HoistableDeclaration로 한다.
  2. 만약 declarationNames"*default*" 요소가 없다면, "*default*"declarationNames에 추가한다.
  3. declarationNames를 반환한다.
ExportDeclaration : export default ClassDeclaration
  1. declarationNamesBoundNames of ClassDeclaration로 한다.
  2. 만약 declarationNames"*default*" 요소가 없다면, "*default*"declarationNames에 추가한다.
  3. declarationNames를 반환한다.
ExportDeclaration : export default AssignmentExpression ;
  1. « "*default*" »를 반환한다.

8.2.2 정적 의미론: DeclarationPart

구문 지향 연산 DeclarationPart는 인자를 받지 않으며 파스 노드를 반환한다. 다음 생산 규칙에 대해 조각별로 정의된다:

HoistableDeclaration : FunctionDeclaration
  1. FunctionDeclaration를 반환한다.
HoistableDeclaration : GeneratorDeclaration
  1. GeneratorDeclaration를 반환한다.
HoistableDeclaration : AsyncFunctionDeclaration
  1. AsyncFunctionDeclaration를 반환한다.
HoistableDeclaration : AsyncGeneratorDeclaration
  1. AsyncGeneratorDeclaration를 반환한다.
Declaration : ClassDeclaration
  1. ClassDeclaration를 반환한다.
Declaration : LexicalDeclaration
  1. LexicalDeclaration를 반환한다.

8.2.3 정적 의미론: IsConstantDeclaration

구문 지향 연산 IsConstantDeclaration은 인자를 받지 않으며 불리언을 반환한다. 다음 생산 규칙에 대해 조각별로 정의된다:

LexicalDeclaration : LetOrConst BindingList ;
  1. IsConstantDeclaration of LetOrConst를 반환한다.
LetOrConst : let
  1. false를 반환한다.
LetOrConst : const
  1. true를 반환한다.
FunctionDeclaration : function BindingIdentifier ( FormalParameters ) { FunctionBody } function ( FormalParameters ) { FunctionBody } GeneratorDeclaration : function * BindingIdentifier ( FormalParameters ) { GeneratorBody } function * ( FormalParameters ) { GeneratorBody } AsyncGeneratorDeclaration : async function * BindingIdentifier ( FormalParameters ) { AsyncGeneratorBody } async function * ( FormalParameters ) { AsyncGeneratorBody } AsyncFunctionDeclaration : async function BindingIdentifier ( FormalParameters ) { AsyncFunctionBody } async function ( FormalParameters ) { AsyncFunctionBody }
  1. false를 반환한다.
ClassDeclaration : class BindingIdentifier ClassTail class ClassTail
  1. false를 반환한다.
ExportDeclaration : export ExportFromClause FromClause ; export NamedExports ; export default AssignmentExpression ;
  1. false를 반환한다.
참고

export default AssignmentExpression를 상수 선언으로 취급할 필요는 없다. 모듈의 default 객체를 참조하는 내부 바운드 이름에 할당을 허용하는 구문이 존재하지 않기 때문이다.

8.2.4 정적 의미론: LexicallyDeclaredNames

구문 지향 연산 LexicallyDeclaredNames는 인자를 받지 않으며 문자열의 리스트를 반환한다. 다음 생산 규칙에 대해 조각별로 정의된다:

Block : { }
  1. 새로운 빈 리스트를 반환한다.
StatementList : StatementList StatementListItem
  1. names1LexicallyDeclaredNames of StatementList로 한다.
  2. names2LexicallyDeclaredNames of StatementListItem로 한다.
  3. list-concatenation of names1names2를 반환한다.
StatementListItem : Statement
  1. 만약 Statement Statement : LabelledStatement 인 경우, LexicallyDeclaredNames of LabelledStatement를 반환한다.
  2. 새로운 빈 리스트를 반환한다.
StatementListItem : Declaration
  1. BoundNames of Declaration를 반환한다.
CaseBlock : { }
  1. 새로운 빈 리스트를 반환한다.
CaseBlock : { CaseClausesopt DefaultClause CaseClausesopt }
  1. 첫 번째 CaseClauses가 존재하면, names1LexicallyDeclaredNames of 첫 번째 CaseClauses로 한다.
  2. 그렇지 않으면, names1을 새로운 빈 리스트로 한다.
  3. names2LexicallyDeclaredNames of DefaultClause로 한다.
  4. 두 번째 CaseClauses가 존재하면, names3LexicallyDeclaredNames of 두 번째 CaseClauses로 한다.
  5. 그렇지 않으면, names3을 새로운 빈 리스트로 한다.
  6. list-concatenation of names1, names2, names3를 반환한다.
CaseClauses : CaseClauses CaseClause
  1. names1LexicallyDeclaredNames of CaseClauses로 한다.
  2. names2LexicallyDeclaredNames of CaseClause로 한다.
  3. list-concatenation of names1names2를 반환한다.
CaseClause : case Expression : StatementListopt
  1. StatementList가 존재하면, LexicallyDeclaredNames of StatementList를 반환한다.
  2. 새로운 빈 리스트를 반환한다.
DefaultClause : default : StatementListopt
  1. StatementList가 존재하면, LexicallyDeclaredNames of StatementList를 반환한다.
  2. 새로운 빈 리스트를 반환한다.
LabelledStatement : LabelIdentifier : LabelledItem
  1. LexicallyDeclaredNames of LabelledItem를 반환한다.
LabelledItem : Statement
  1. 새로운 빈 리스트를 반환한다.
LabelledItem : FunctionDeclaration
  1. BoundNames of FunctionDeclaration를 반환한다.
FunctionStatementList : [empty]
  1. 새로운 빈 리스트를 반환한다.
FunctionStatementList : StatementList
  1. TopLevelLexicallyDeclaredNames of StatementList를 반환한다.
ClassStaticBlockStatementList : [empty]
  1. 새로운 빈 리스트를 반환한다.
ClassStaticBlockStatementList : StatementList
  1. TopLevelLexicallyDeclaredNames of StatementList를 반환한다.
ConciseBody : ExpressionBody
  1. 새로운 빈 리스트를 반환한다.
AsyncConciseBody : ExpressionBody
  1. 새로운 빈 리스트를 반환한다.
Script : [empty]
  1. 새로운 빈 리스트를 반환한다.
ScriptBody : StatementList
  1. TopLevelLexicallyDeclaredNames of StatementList를 반환한다.
참고 1

Script의 최상위 레벨에서는, 함수 선언이 렉시컬 선언이 아니라 var 선언처럼 취급된다.

참고 2

Module의 LexicallyDeclaredNames에는 그 안의 모든 import 바인딩의 이름이 포함된다.

ModuleItemList : ModuleItemList ModuleItem
  1. names1LexicallyDeclaredNames of ModuleItemList로 한다.
  2. names2LexicallyDeclaredNames of ModuleItem로 한다.
  3. list-concatenation of names1names2를 반환한다.
ModuleItem : ImportDeclaration
  1. BoundNames of ImportDeclaration를 반환한다.
ModuleItem : ExportDeclaration
  1. 만약 ExportDeclarationexport VariableStatement인 경우, 새로운 빈 리스트를 반환한다.
  2. BoundNames of ExportDeclaration를 반환한다.
ModuleItem : StatementListItem
  1. LexicallyDeclaredNames of StatementListItem를 반환한다.
참고 3

Module의 최상위 레벨에서는, 함수 선언이 var 선언이 아니라 렉시컬 선언처럼 취급된다.

8.2.5 정적 의미론: LexicallyScopedDeclarations

구문 지향 연산 LexicallyScopedDeclarations는 인자를 받지 않으며 리스트 (파스 노드의 리스트)를 반환한다. 다음 생산 규칙에 대해 조각별로 정의된다:

StatementList : StatementList StatementListItem
  1. declarations1LexicallyScopedDeclarations of StatementList로 한다.
  2. declarations2LexicallyScopedDeclarations of StatementListItem로 한다.
  3. list-concatenation of declarations1declarations2를 반환한다.
StatementListItem : Statement
  1. 만약 Statement Statement : LabelledStatement 인 경우, LexicallyScopedDeclarations of LabelledStatement를 반환한다.
  2. 새로운 빈 리스트를 반환한다.
StatementListItem : Declaration
  1. 리스트를 반환한다. 유일한 요소는 DeclarationPart of Declaration이다.
CaseBlock : { }
  1. 새로운 빈 리스트를 반환한다.
CaseBlock : { CaseClausesopt DefaultClause CaseClausesopt }
  1. 첫 번째 CaseClauses가 존재하면, declarations1LexicallyScopedDeclarations of 첫 번째 CaseClauses로 한다.
  2. 그렇지 않으면, declarations1을 새로운 빈 리스트로 한다.
  3. declarations2LexicallyScopedDeclarations of DefaultClause로 한다.
  4. 두 번째 CaseClauses가 존재하면, declarations3LexicallyScopedDeclarations of 두 번째 CaseClauses로 한다.
  5. 그렇지 않으면, declarations3을 새로운 빈 리스트로 한다.
  6. list-concatenation of declarations1, declarations2, declarations3를 반환한다.
CaseClauses : CaseClauses CaseClause
  1. declarations1LexicallyScopedDeclarations of CaseClauses로 한다.
  2. declarations2LexicallyScopedDeclarations of CaseClause로 한다.
  3. list-concatenation of declarations1declarations2를 반환한다.
CaseClause : case Expression : StatementListopt
  1. StatementList가 존재하면, LexicallyScopedDeclarations of StatementList를 반환한다.
  2. 새로운 빈 리스트를 반환한다.
DefaultClause : default : StatementListopt
  1. StatementList가 존재하면, LexicallyScopedDeclarations of StatementList를 반환한다.
  2. 새로운 빈 리스트를 반환한다.
LabelledStatement : LabelIdentifier : LabelledItem
  1. LexicallyScopedDeclarations of LabelledItem를 반환한다.
LabelledItem : Statement
  1. 새로운 빈 리스트를 반환한다.
LabelledItem : FunctionDeclaration
  1. « FunctionDeclaration »를 반환한다.
FunctionStatementList : [empty]
  1. 새로운 빈 리스트를 반환한다.
FunctionStatementList : StatementList
  1. TopLevelLexicallyScopedDeclarations of StatementList를 반환한다.
ClassStaticBlockStatementList : [empty]
  1. 새로운 빈 리스트를 반환한다.
ClassStaticBlockStatementList : StatementList
  1. TopLevelLexicallyScopedDeclarations of StatementList를 반환한다.
ConciseBody : ExpressionBody
  1. 새로운 빈 리스트를 반환한다.
AsyncConciseBody : ExpressionBody
  1. 새로운 빈 리스트를 반환한다.
Script : [empty]
  1. 새로운 빈 리스트를 반환한다.
ScriptBody : StatementList
  1. TopLevelLexicallyScopedDeclarations of StatementList를 반환한다.
Module : [empty]
  1. 새로운 빈 리스트를 반환한다.
ModuleItemList : ModuleItemList ModuleItem
  1. declarations1LexicallyScopedDeclarations of ModuleItemList로 한다.
  2. declarations2LexicallyScopedDeclarations of ModuleItem로 한다.
  3. list-concatenation of declarations1declarations2를 반환한다.
ModuleItem : ImportDeclaration
  1. 새로운 빈 리스트를 반환한다.
ExportDeclaration : export ExportFromClause FromClause WithClauseopt ; export NamedExports ; export VariableStatement
  1. 새로운 빈 리스트를 반환한다.
ExportDeclaration : export Declaration
  1. 리스트를 반환한다. 유일한 요소는 DeclarationPart of Declaration이다.
ExportDeclaration : export default HoistableDeclaration
  1. 리스트를 반환한다. 유일한 요소는 DeclarationPart of HoistableDeclaration이다.
ExportDeclaration : export default ClassDeclaration
  1. 리스트를 반환한다. 유일한 요소는 ClassDeclaration이다.
ExportDeclaration : export default AssignmentExpression ;
  1. 리스트를 반환한다. 유일한 요소는 이 ExportDeclaration이다.

8.2.6 정적 의미론: VarDeclaredNames

구문 지향 연산 VarDeclaredNames는 인자를 받지 않으며 문자열의 리스트를 반환한다. 다음 생산 규칙에 대해 조각별로 정의된다:

Statement : EmptyStatement ExpressionStatement ContinueStatement BreakStatement ReturnStatement ThrowStatement DebuggerStatement
  1. 새로운 빈 리스트를 반환한다.
Block : { }
  1. 새로운 빈 리스트를 반환한다.
StatementList : StatementList StatementListItem
  1. names1VarDeclaredNames of StatementList로 한다.
  2. names2VarDeclaredNames of StatementListItem로 한다.
  3. list-concatenation of names1names2를 반환한다.
StatementListItem : Declaration
  1. 새로운 빈 리스트를 반환한다.
VariableStatement : var VariableDeclarationList ;
  1. BoundNames of VariableDeclarationList를 반환한다.
IfStatement : if ( Expression ) Statement else Statement
  1. names1VarDeclaredNames of 첫 번째 Statement로 한다.
  2. names2VarDeclaredNames of 두 번째 Statement로 한다.
  3. list-concatenation of names1names2를 반환한다.
IfStatement : if ( Expression ) Statement
  1. VarDeclaredNames of Statement를 반환한다.
DoWhileStatement : do Statement while ( Expression ) ;
  1. VarDeclaredNames of Statement를 반환한다.
WhileStatement : while ( Expression ) Statement
  1. VarDeclaredNames of Statement를 반환한다.
ForStatement : for ( Expressionopt ; Expressionopt ; Expressionopt ) Statement
  1. VarDeclaredNames of Statement를 반환한다.
ForStatement : for ( var VariableDeclarationList ; Expressionopt ; Expressionopt ) Statement
  1. names1BoundNames of VariableDeclarationList로 한다.
  2. names2VarDeclaredNames of Statement로 한다.
  3. list-concatenation of names1names2를 반환한다.
ForStatement : for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement
  1. VarDeclaredNames of Statement를 반환한다.
ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement for ( ForDeclaration in Expression ) Statement for ( LeftHandSideExpression of AssignmentExpression ) Statement for ( ForDeclaration of AssignmentExpression ) Statement for await ( LeftHandSideExpression of AssignmentExpression ) Statement for await ( ForDeclaration of AssignmentExpression ) Statement
  1. VarDeclaredNames of Statement를 반환한다.
ForInOfStatement : for ( var ForBinding in Expression ) Statement for ( var ForBinding of AssignmentExpression ) Statement for await ( var ForBinding of AssignmentExpression ) Statement
  1. names1BoundNames of ForBinding로 한다.
  2. names2VarDeclaredNames of Statement로 한다.
  3. list-concatenation of names1names2를 반환한다.
참고

이 절은 부록 B.3.5에 의해 확장된다.

WithStatement : with ( Expression ) Statement
  1. VarDeclaredNames of Statement를 반환한다.
SwitchStatement : switch ( Expression ) CaseBlock
  1. VarDeclaredNames of CaseBlock를 반환한다.
CaseBlock : { }
  1. 새로운 빈 리스트를 반환한다.
CaseBlock : { CaseClausesopt DefaultClause CaseClausesopt }
  1. 첫 번째 CaseClauses가 존재하면, names1VarDeclaredNames of 첫 번째 CaseClauses로 한다.
  2. 그렇지 않으면, names1을 새로운 빈 리스트로 한다.
  3. names2VarDeclaredNames of DefaultClause로 한다.
  4. 두 번째 CaseClauses가 존재하면, names3VarDeclaredNames of 두 번째 CaseClauses로 한다.
  5. 그렇지 않으면, names3을 새로운 빈 리스트로 한다.
  6. list-concatenation of names1, names2, names3를 반환한다.
CaseClauses : CaseClauses CaseClause
  1. names1VarDeclaredNames of CaseClauses로 한다.
  2. names2VarDeclaredNames of CaseClause로 한다.
  3. list-concatenation of names1names2를 반환한다.
CaseClause : case Expression : StatementListopt
  1. StatementList가 존재하면, VarDeclaredNames of StatementList를 반환한다.
  2. 새로운 빈 리스트를 반환한다.
DefaultClause : default : StatementListopt
  1. StatementList가 존재하면, VarDeclaredNames of StatementList를 반환한다.
  2. 새로운 빈 리스트를 반환한다.
LabelledStatement : LabelIdentifier : LabelledItem
  1. VarDeclaredNames of LabelledItem를 반환한다.
LabelledItem : FunctionDeclaration
  1. 새로운 빈 리스트를 반환한다.
TryStatement : try Block Catch
  1. names1VarDeclaredNames of Block로 한다.
  2. names2VarDeclaredNames of Catch로 한다.
  3. list-concatenation of names1names2를 반환한다.
TryStatement : try Block Finally
  1. names1VarDeclaredNames of Block로 한다.
  2. names2VarDeclaredNames of Finally로 한다.
  3. list-concatenation of names1names2를 반환한다.
TryStatement : try Block Catch Finally
  1. names1VarDeclaredNames of Block로 한다.
  2. names2VarDeclaredNames of Catch로 한다.
  3. names3VarDeclaredNames of Finally로 한다.
  4. list-concatenation of names1, names2, names3를 반환한다.
Catch : catch ( CatchParameter ) Block
  1. VarDeclaredNames of Block를 반환한다.
FunctionStatementList : [empty]
  1. 새로운 빈 리스트를 반환한다.
FunctionStatementList : StatementList
  1. TopLevelVarDeclaredNames of StatementList를 반환한다.
ClassStaticBlockStatementList : [empty]
  1. 새로운 빈 리스트를 반환한다.
ClassStaticBlockStatementList : StatementList
  1. TopLevelVarDeclaredNames of StatementList를 반환한다.
ConciseBody : ExpressionBody
  1. 새로운 빈 리스트를 반환한다.
AsyncConciseBody : ExpressionBody
  1. 새로운 빈 리스트를 반환한다.
Script : [empty]
  1. 새로운 빈 리스트를 반환한다.
ScriptBody : StatementList
  1. TopLevelVarDeclaredNames of StatementList를 반환한다.
ModuleItemList : ModuleItemList ModuleItem
  1. names1VarDeclaredNames of ModuleItemList로 한다.
  2. names2VarDeclaredNames of ModuleItem로 한다.
  3. list-concatenation of names1names2를 반환한다.
ModuleItem : ImportDeclaration
  1. 새로운 빈 리스트를 반환한다.
ModuleItem : ExportDeclaration
  1. 만약 ExportDeclarationexport VariableStatement인 경우, BoundNames of ExportDeclaration를 반환한다.
  2. 새로운 빈 리스트를 반환한다.

8.2.7 정적 의미론: VarScopedDeclarations

구문 지향 연산 VarScopedDeclarations는 인자를 받지 않으며 리스트 (파스 노드의 리스트)를 반환한다. 다음 생산 규칙에 대해 조각별로 정의된다:

Statement : EmptyStatement ExpressionStatement ContinueStatement BreakStatement ReturnStatement ThrowStatement DebuggerStatement
  1. 새로운 빈 리스트를 반환한다.
Block : { }
  1. 새로운 빈 리스트를 반환한다.
StatementList : StatementList StatementListItem
  1. declarations1VarScopedDeclarations of StatementList로 한다.
  2. declarations2VarScopedDeclarations of StatementListItem로 한다.
  3. list-concatenation of declarations1declarations2를 반환한다.
StatementListItem : Declaration
  1. 새로운 빈 리스트를 반환한다.
VariableDeclarationList : VariableDeclaration
  1. « VariableDeclaration »를 반환한다.
VariableDeclarationList : VariableDeclarationList , VariableDeclaration
  1. declarations1VarScopedDeclarations of VariableDeclarationList로 한다.
  2. list-concatenation of declarations1과 « VariableDeclaration »를 반환한다.
IfStatement : if ( Expression ) Statement else Statement
  1. declarations1VarScopedDeclarations of 첫 번째 Statement로 한다.
  2. declarations2VarScopedDeclarations of 두 번째 Statement로 한다.
  3. list-concatenation of declarations1declarations2를 반환한다.
IfStatement : if ( Expression ) Statement
  1. VarScopedDeclarations of Statement를 반환한다.
DoWhileStatement : do Statement while ( Expression ) ;
  1. VarScopedDeclarations of Statement를 반환한다.
WhileStatement : while ( Expression ) Statement
  1. VarScopedDeclarations of Statement를 반환한다.
ForStatement : for ( Expressionopt ; Expressionopt ; Expressionopt ) Statement
  1. VarScopedDeclarations of Statement를 반환한다.
ForStatement : for ( var VariableDeclarationList ; Expressionopt ; Expressionopt ) Statement
  1. declarations1VarScopedDeclarations of VariableDeclarationList로 한다.
  2. declarations2VarScopedDeclarations of Statement로 한다.
  3. list-concatenation of declarations1declarations2를 반환한다.
ForStatement : for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement
  1. VarScopedDeclarations of Statement를 반환한다.
ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement for ( ForDeclaration in Expression ) Statement for ( LeftHandSideExpression of AssignmentExpression ) Statement for ( ForDeclaration of AssignmentExpression ) Statement for await ( LeftHandSideExpression of AssignmentExpression ) Statement for await ( ForDeclaration of AssignmentExpression ) Statement
  1. VarScopedDeclarations of Statement를 반환한다.
ForInOfStatement : for ( var ForBinding in Expression ) Statement for ( var ForBinding of AssignmentExpression ) Statement for await ( var ForBinding of AssignmentExpression ) Statement
  1. declarations1을(를) « ForBinding »로 둔다.
  2. declarations2을(를) VarScopedDeclarations of Statement로 둔다.
  3. list-concatenation을(를) declarations1declarations2에 대해 반환한다.
참고

이 섹션은 부록 B.3.5에서 확장됩니다.

WithStatement : with ( Expression ) Statement
  1. VarScopedDeclarations of Statement을(를) 반환한다.
SwitchStatement : switch ( Expression ) CaseBlock
  1. VarScopedDeclarations of CaseBlock을(를) 반환한다.
CaseBlock : { }
  1. 새로운 빈 List를 반환한다.
CaseBlock : { CaseClausesopt DefaultClause CaseClausesopt }
  1. 첫 번째 CaseClauses가 존재하면, declarations1을(를) 첫 번째 VarScopedDeclarations of CaseClauses로 둔다.
  2. 그렇지 않으면, declarations1을(를) 새로운 빈 List로 둔다.
  3. declarations2을(를) VarScopedDeclarations of DefaultClause로 둔다.
  4. 두 번째 CaseClauses가 존재하면, declarations3을(를) 두 번째 VarScopedDeclarations of CaseClauses로 둔다.
  5. 그렇지 않으면, declarations3을(를) 새로운 빈 List로 둔다.
  6. list-concatenation을(를) declarations1, declarations2, declarations3에 대해 반환한다.
CaseClauses : CaseClauses CaseClause
  1. declarations1을(를) VarScopedDeclarations of CaseClauses로 둔다.
  2. declarations2을(를) VarScopedDeclarations of CaseClause로 둔다.
  3. list-concatenation을(를) declarations1declarations2에 대해 반환한다.
CaseClause : case Expression : StatementListopt
  1. StatementList 가 존재하면, VarScopedDeclarations of StatementList을(를) 반환한다.
  2. 새로운 빈 List를 반환한다.
DefaultClause : default : StatementListopt
  1. StatementList 가 존재하면, VarScopedDeclarations of StatementList을(를) 반환한다.
  2. 새로운 빈 List를 반환한다.
LabelledStatement : LabelIdentifier : LabelledItem
  1. VarScopedDeclarations of LabelledItem을(를) 반환한다.
LabelledItem : FunctionDeclaration
  1. 새로운 빈 List를 반환한다.
TryStatement : try Block Catch
  1. declarations1을(를) VarScopedDeclarations of Block로 둔다.
  2. declarations2을(를) VarScopedDeclarations of Catch로 둔다.
  3. list-concatenation을(를) declarations1declarations2에 대해 반환한다.
TryStatement : try Block Finally
  1. declarations1을(를) VarScopedDeclarations of Block로 둔다.
  2. declarations2을(를) VarScopedDeclarations of Finally로 둔다.
  3. list-concatenation을(를) declarations1declarations2에 대해 반환한다.
TryStatement : try Block Catch Finally
  1. declarations1을(를) VarScopedDeclarations of Block로 둔다.
  2. declarations2을(를) VarScopedDeclarations of Catch로 둔다.
  3. declarations3을(를) VarScopedDeclarations of Finally로 둔다.
  4. list-concatenation을(를) declarations1, declarations2, declarations3에 대해 반환한다.
Catch : catch ( CatchParameter ) Block
  1. VarScopedDeclarations of Block을(를) 반환한다.
FunctionStatementList : [empty]
  1. 새로운 빈 List를 반환한다.
FunctionStatementList : StatementList
  1. TopLevelVarScopedDeclarations of StatementList를 반환한다.
ClassStaticBlockStatementList : [empty]
  1. 새로운 빈 List를 반환한다.
ClassStaticBlockStatementList : StatementList
  1. TopLevelVarScopedDeclarations of StatementList를 반환한다.
ConciseBody : ExpressionBody
  1. 새로운 빈 List를 반환한다.
AsyncConciseBody : ExpressionBody
  1. 새로운 빈 List를 반환한다.
Script : [empty]
  1. 새로운 빈 List를 반환한다.
ScriptBody : StatementList
  1. TopLevelVarScopedDeclarations of StatementList를 반환한다.
Module : [empty]
  1. 새로운 빈 List를 반환한다.
ModuleItemList : ModuleItemList ModuleItem
  1. declarations1을(를) VarScopedDeclarations of ModuleItemList로 둔다.
  2. declarations2을(를) VarScopedDeclarations of ModuleItem로 둔다.
  3. list-concatenation을(를) declarations1declarations2에 대해 반환한다.
ModuleItem : ImportDeclaration
  1. 새로운 빈 List를 반환한다.
ModuleItem : ExportDeclaration
  1. ExportDeclaration이(가) export VariableStatement라면, VarScopedDeclarations of VariableStatement을(를) 반환한다.
  2. 새로운 빈 List를 반환한다.

8.2.8 정적 의미론: TopLevelLexicallyDeclaredNames

구문 지시 연산 TopLevelLexicallyDeclaredNames는 인자가 없으며 문자열의 List를 반환한다. 다음 생성 규칙에 대해 조각별로 정의된다:

StatementList : StatementList StatementListItem
  1. names1TopLevelLexicallyDeclaredNames of StatementList로 둔다.
  2. names2TopLevelLexicallyDeclaredNames of StatementListItem로 둔다.
  3. list-concatenationnames1names2에 대해 반환한다.
StatementListItem : Statement
  1. 새 빈 List를 반환한다.
StatementListItem : Declaration
  1. Declaration Declaration : HoistableDeclaration 라면,
    1. 새 빈 List를 반환한다.
  2. BoundNames of Declaration를 반환한다.
참고

함수나 스크립트의 최상위 레벨에서는 함수 선언이 렉시컬 선언이 아닌 var 선언처럼 취급된다.

8.2.9 정적 의미론: TopLevelLexicallyScopedDeclarations

구문 지시 연산 TopLevelLexicallyScopedDeclarations는 인자가 없으며 List구문 노드를 반환한다. 다음 생성 규칙에 대해 조각별로 정의된다:

StatementList : StatementList StatementListItem
  1. declarations1TopLevelLexicallyScopedDeclarations of StatementList로 둔다.
  2. declarations2TopLevelLexicallyScopedDeclarations of StatementListItem로 둔다.
  3. list-concatenationdeclarations1declarations2에 대해 반환한다.
StatementListItem : Statement
  1. 새 빈 List를 반환한다.
StatementListItem : Declaration
  1. Declaration Declaration : HoistableDeclaration 라면,
    1. 새 빈 List를 반환한다.
  2. « Declaration »를 반환한다.

8.2.10 정적 의미론: TopLevelVarDeclaredNames

구문 지시 연산 TopLevelVarDeclaredNames는 인자가 없으며 문자열의 List를 반환한다. 다음 생성 규칙에 대해 조각별로 정의된다:

StatementList : StatementList StatementListItem
  1. names1TopLevelVarDeclaredNames of StatementList로 둔다.
  2. names2TopLevelVarDeclaredNames of StatementListItem로 둔다.
  3. list-concatenationnames1names2에 대해 반환한다.
StatementListItem : Declaration
  1. Declaration Declaration : HoistableDeclaration 라면,
    1. BoundNames of HoistableDeclaration를 반환한다.
  2. 새 빈 List를 반환한다.
StatementListItem : Statement
  1. Statement Statement : LabelledStatement 라면, TopLevelVarDeclaredNames of Statement를 반환한다.
  2. VarDeclaredNames of Statement를 반환한다.
참고

함수 또는 스크립트의 최상위 레벨에서 내부 함수 선언은 var 선언으로 취급된다.

LabelledStatement : LabelIdentifier : LabelledItem
  1. TopLevelVarDeclaredNames of LabelledItem를 반환한다.
LabelledItem : Statement
  1. Statement Statement : LabelledStatement 라면, TopLevelVarDeclaredNames of Statement를 반환한다.
  2. VarDeclaredNames of Statement를 반환한다.
LabelledItem : FunctionDeclaration
  1. BoundNames of FunctionDeclaration를 반환한다.

8.2.11 정적 의미론: TopLevelVarScopedDeclarations

구문 지시 연산 TopLevelVarScopedDeclarations는 인자를 받지 않고 List파스 노드를 반환한다. 다음 생성 규칙에 대해 조각별로 정의된다:

StatementList : StatementList StatementListItem
  1. declarations1TopLevelVarScopedDeclarations of StatementList로 둔다.
  2. declarations2TopLevelVarScopedDeclarations of StatementListItem로 둔다.
  3. list-concatenationdeclarations1declarations2에 대해 반환한다.
StatementListItem : Statement
  1. Statement Statement : LabelledStatement 라면, TopLevelVarScopedDeclarations of Statement를 반환한다.
  2. VarScopedDeclarations of Statement를 반환한다.
StatementListItem : Declaration
  1. Declaration Declaration : HoistableDeclaration 라면,
    1. declarationDeclarationPart of HoistableDeclaration로 둔다.
    2. « declaration »를 반환한다.
  2. 새 빈 List를 반환한다.
LabelledStatement : LabelIdentifier : LabelledItem
  1. TopLevelVarScopedDeclarations of LabelledItem를 반환한다.
LabelledItem : Statement
  1. Statement Statement : LabelledStatement 라면, TopLevelVarScopedDeclarations of Statement를 반환한다.
  2. VarScopedDeclarations of Statement를 반환한다.
LabelledItem : FunctionDeclaration
  1. « FunctionDeclaration »를 반환한다.

8.3 레이블

8.3.1 정적 의미론: ContainsDuplicateLabels

구문 지시 연산 ContainsDuplicateLabels는 labelSet (문자열의 List) 인자를 받고, Boolean을 반환한다. 이는 다음 생성 규칙에 대해 조각별로 정의된다:

Statement : VariableStatement EmptyStatement ExpressionStatement ContinueStatement BreakStatement ReturnStatement ThrowStatement DebuggerStatement Block : { } StatementListItem : Declaration
  1. false를 반환한다.
StatementList : StatementList StatementListItem
  1. hasDuplicatesContainsDuplicateLabels of StatementList (인자 labelSet)로 둔다.
  2. 만약 hasDuplicatestrue라면, true를 반환한다.
  3. ContainsDuplicateLabels of StatementListItem (인자 labelSet)를 반환한다.
IfStatement : if ( Expression ) Statement else Statement
  1. hasDuplicateContainsDuplicateLabels of 첫 번째 Statement (인자 labelSet)로 둔다.
  2. 만약 hasDuplicatetrue라면, true를 반환한다.
  3. 두 번째 ContainsDuplicateLabels of Statement (인자 labelSet)를 반환한다.
IfStatement : if ( Expression ) Statement
  1. ContainsDuplicateLabels of Statement (인자 labelSet)를 반환한다.
DoWhileStatement : do Statement while ( Expression ) ;
  1. ContainsDuplicateLabels of Statement (인자 labelSet)를 반환한다.
WhileStatement : while ( Expression ) Statement
  1. ContainsDuplicateLabels of Statement (인자 labelSet)를 반환한다.
ForStatement : for ( Expressionopt ; Expressionopt ; Expressionopt ) Statement for ( var VariableDeclarationList ; Expressionopt ; Expressionopt ) Statement for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement
  1. ContainsDuplicateLabels of Statement (인자 labelSet)를 반환한다.
ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement for ( var ForBinding in Expression ) Statement for ( ForDeclaration in Expression ) Statement for ( LeftHandSideExpression of AssignmentExpression ) Statement for ( var ForBinding of AssignmentExpression ) Statement for ( ForDeclaration of AssignmentExpression ) Statement for await ( LeftHandSideExpression of AssignmentExpression ) Statement for await ( var ForBinding of AssignmentExpression ) Statement for await ( ForDeclaration of AssignmentExpression ) Statement
  1. ContainsDuplicateLabels of Statement (인자 labelSet)를 반환한다.
참고

이 섹션은 부록 B.3.5에서 확장된다.

WithStatement : with ( Expression ) Statement
  1. ContainsDuplicateLabels of Statement (인자 labelSet)를 반환한다.
SwitchStatement : switch ( Expression ) CaseBlock
  1. ContainsDuplicateLabels of CaseBlock (인자 labelSet)를 반환한다.
CaseBlock : { }
  1. false를 반환한다.
CaseBlock : { CaseClausesopt DefaultClause CaseClausesopt }
  1. 첫 번째 CaseClauses가 존재하면,
    1. 첫 번째 ContainsDuplicateLabels of CaseClauses (인자 labelSet)가 true라면, true를 반환한다.
  2. ContainsDuplicateLabels of DefaultClause (인자 labelSet)가 true라면, true를 반환한다.
  3. 두 번째 CaseClauses가 존재하지 않으면, false를 반환한다.
  4. 두 번째 ContainsDuplicateLabels of CaseClauses (인자 labelSet)를 반환한다.
CaseClauses : CaseClauses CaseClause
  1. hasDuplicatesContainsDuplicateLabels of CaseClauses (인자 labelSet)로 둔다.
  2. hasDuplicatestrue라면, true를 반환한다.
  3. ContainsDuplicateLabels of CaseClause (인자 labelSet)를 반환한다.
CaseClause : case Expression : StatementListopt
  1. StatementList가 존재하면, ContainsDuplicateLabels of StatementList (인자 labelSet)를 반환한다.
  2. false를 반환한다.
DefaultClause : default : StatementListopt
  1. StatementList가 존재하면, ContainsDuplicateLabels of StatementList (인자 labelSet)를 반환한다.
  2. false를 반환한다.
LabelledStatement : LabelIdentifier : LabelledItem
  1. labelStringValue of LabelIdentifier로 둔다.
  2. labelSetlabel이 포함되어 있으면, true를 반환한다.
  3. newLabelSetlist-concatenation of labelSet 및 « label »로 둔다.
  4. ContainsDuplicateLabels of LabelledItem (인자 newLabelSet)를 반환한다.
LabelledItem : FunctionDeclaration
  1. false를 반환한다.
TryStatement : try Block Catch
  1. hasDuplicatesContainsDuplicateLabels of Block (인자 labelSet)로 둔다.
  2. hasDuplicatestrue라면, true를 반환한다.
  3. ContainsDuplicateLabels of Catch (인자 labelSet)를 반환한다.
TryStatement : try Block Finally
  1. hasDuplicatesContainsDuplicateLabels of Block (인자 labelSet)로 둔다.
  2. hasDuplicatestrue라면, true를 반환한다.
  3. ContainsDuplicateLabels of Finally (인자 labelSet)를 반환한다.
TryStatement : try Block Catch Finally
  1. ContainsDuplicateLabels of Block (인자 labelSet)가 true라면, true를 반환한다.
  2. ContainsDuplicateLabels of Catch (인자 labelSet)가 true라면, true를 반환한다.
  3. ContainsDuplicateLabels of Finally (인자 labelSet)를 반환한다.
Catch : catch ( CatchParameter ) Block
  1. ContainsDuplicateLabels of Block (인자 labelSet)를 반환한다.
FunctionStatementList : [empty]
  1. false를 반환한다.
ClassStaticBlockStatementList : [empty]
  1. false를 반환한다.
ModuleItemList : ModuleItemList ModuleItem
  1. hasDuplicatesContainsDuplicateLabels of ModuleItemList (인자 labelSet)로 둔다.
  2. hasDuplicatestrue라면, true를 반환한다.
  3. ContainsDuplicateLabels of ModuleItem (인자 labelSet)를 반환한다.
ModuleItem : ImportDeclaration ExportDeclaration
  1. false를 반환한다.

8.3.2 정적 의미론: ContainsUndefinedBreakTarget

구문 지향 연산 ContainsUndefinedBreakTarget는 labelSet (문자열의 List) 인수를 받고 불리언을 반환한다. 다음 생성 규칙들에 대해 조각별로 정의된다:

Statement : VariableStatement EmptyStatement ExpressionStatement ContinueStatement ReturnStatement ThrowStatement DebuggerStatement Block : { } StatementListItem : Declaration
  1. false를 반환한다.
StatementList : StatementList StatementListItem
  1. hasUndefinedLabelsContainsUndefinedBreakTarget (StatementList, labelSet 인수)로 한다.
  2. hasUndefinedLabelstrue이면, true를 반환한다.
  3. ContainsUndefinedBreakTarget (StatementListItem, labelSet 인수)를 반환한다.
IfStatement : if ( Expression ) Statement else Statement
  1. hasUndefinedLabels를 첫 번째 StatementlabelSet 인수로 ContainsUndefinedBreakTarget의 결과로 한다.
  2. hasUndefinedLabelstrue이면, true를 반환한다.
  3. 두 번째 StatementlabelSet 인수로 ContainsUndefinedBreakTarget의 결과를 반환한다.
IfStatement : if ( Expression ) Statement
  1. ContainsUndefinedBreakTarget (Statement, labelSet 인수)를 반환한다.
DoWhileStatement : do Statement while ( Expression ) ;
  1. ContainsUndefinedBreakTarget (Statement, labelSet 인수)를 반환한다.
WhileStatement : while ( Expression ) Statement
  1. ContainsUndefinedBreakTarget (Statement, labelSet 인수)를 반환한다.
ForStatement : for ( Expressionopt ; Expressionopt ; Expressionopt ) Statement for ( var VariableDeclarationList ; Expressionopt ; Expressionopt ) Statement for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement
  1. ContainsUndefinedBreakTarget (Statement, labelSet 인수)를 반환한다.
ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement for ( var ForBinding in Expression ) Statement for ( ForDeclaration in Expression ) Statement for ( LeftHandSideExpression of AssignmentExpression ) Statement for ( var ForBinding of AssignmentExpression ) Statement for ( ForDeclaration of AssignmentExpression ) Statement for await ( LeftHandSideExpression of AssignmentExpression ) Statement for await ( var ForBinding of AssignmentExpression ) Statement for await ( ForDeclaration of AssignmentExpression ) Statement
  1. ContainsUndefinedBreakTarget (Statement, labelSet 인수)를 반환한다.
참고

이 절은 부록 B.3.5에 의해 확장된다.

BreakStatement : break ;
  1. false를 반환한다.
BreakStatement : break LabelIdentifier ;
  1. labelSetStringValue (LabelIdentifier)가 포함되어 있지 않으면 true를 반환한다.
  2. false를 반환한다.
WithStatement : with ( Expression ) Statement
  1. ContainsUndefinedBreakTarget (Statement, labelSet 인수)를 반환한다.
SwitchStatement : switch ( Expression ) CaseBlock
  1. ContainsUndefinedBreakTarget (CaseBlock, labelSet 인수)를 반환한다.
CaseBlock : { }
  1. false를 반환한다.
CaseBlock : { CaseClausesopt DefaultClause CaseClausesopt }
  1. 첫 번째 CaseClauses가 있으면,
    1. 첫 번째 CaseClauseslabelSet 인수로 ContainsUndefinedBreakTarget의 결과가 true이면 true를 반환한다.
  2. DefaultClauselabelSet 인수로 ContainsUndefinedBreakTarget의 결과가 true이면 true를 반환한다.
  3. 두 번째 CaseClauses가 없으면 false를 반환한다.
  4. 두 번째 CaseClauseslabelSet 인수로 ContainsUndefinedBreakTarget의 결과를 반환한다.
CaseClauses : CaseClauses CaseClause
  1. hasUndefinedLabelsContainsUndefinedBreakTarget (CaseClauses, labelSet 인수)로 한다.
  2. hasUndefinedLabelstrue이면, true를 반환한다.
  3. ContainsUndefinedBreakTarget (CaseClause, labelSet 인수)를 반환한다.
CaseClause : case Expression : StatementListopt
  1. StatementList가 있으면 ContainsUndefinedBreakTarget (StatementList, labelSet 인수)를 반환한다.
  2. false를 반환한다.
DefaultClause : default : StatementListopt
  1. StatementList가 있으면 ContainsUndefinedBreakTarget (StatementList, labelSet 인수)를 반환한다.
  2. false를 반환한다.
LabelledStatement : LabelIdentifier : LabelledItem
  1. labelStringValue(LabelIdentifier)로 한다.
  2. newLabelSetlist-concatenation(labelSet, « label  »)로 한다.
  3. ContainsUndefinedBreakTarget (LabelledItem, newLabelSet 인수)를 반환한다.
LabelledItem : FunctionDeclaration
  1. false를 반환한다.
TryStatement : try Block Catch
  1. hasUndefinedLabelsContainsUndefinedBreakTarget (Block, labelSet 인수)로 한다.
  2. hasUndefinedLabelstrue이면, true를 반환한다.
  3. ContainsUndefinedBreakTarget (Catch, labelSet 인수)를 반환한다.
TryStatement : try Block Finally
  1. hasUndefinedLabelsContainsUndefinedBreakTarget (Block, labelSet 인수)로 한다.
  2. hasUndefinedLabelstrue이면, true를 반환한다.
  3. ContainsUndefinedBreakTarget (Finally, labelSet 인수)를 반환한다.
TryStatement : try Block Catch Finally
  1. ContainsUndefinedBreakTarget (Block, labelSet 인수)가 true이면 true를 반환한다.
  2. ContainsUndefinedBreakTarget (Catch, labelSet 인수)가 true이면 true를 반환한다.
  3. ContainsUndefinedBreakTarget (Finally, labelSet 인수)를 반환한다.
Catch : catch ( CatchParameter ) Block
  1. ContainsUndefinedBreakTarget (Block, labelSet 인수)를 반환한다.
FunctionStatementList : [empty]
  1. false를 반환한다.
ClassStaticBlockStatementList : [empty]
  1. false를 반환한다.
ModuleItemList : ModuleItemList ModuleItem
  1. hasUndefinedLabelsContainsUndefinedBreakTarget (ModuleItemList, labelSet 인수)로 한다.
  2. hasUndefinedLabelstrue이면, true를 반환한다.
  3. ContainsUndefinedBreakTarget (ModuleItem, labelSet 인수)를 반환한다.
ModuleItem : ImportDeclaration ExportDeclaration
  1. false를 반환한다.

8.3.3 정적 의미론: ContainsUndefinedContinueTarget

구문 지향 연산 ContainsUndefinedContinueTarget는 iterationSet (문자열의 List), labelSet (문자열의 List) 인수를 받고 불리언을 반환한다. 다음 생성 규칙들에 대해 조각별로 정의된다:

Statement : VariableStatement EmptyStatement ExpressionStatement BreakStatement ReturnStatement ThrowStatement DebuggerStatement Block : { } StatementListItem : Declaration
  1. false를 반환한다.
Statement : BlockStatement
  1. ContainsUndefinedContinueTarget (BlockStatement, iterationSet, « »)의 결과를 반환한다.
BreakableStatement : IterationStatement
  1. newIterationSetlist-concatenation(iterationSet, labelSet)로 한다.
  2. ContainsUndefinedContinueTarget (IterationStatement, newIterationSet, « »)의 결과를 반환한다.
StatementList : StatementList StatementListItem
  1. hasUndefinedLabelsContainsUndefinedContinueTarget (StatementList, iterationSet, « »)의 결과로 한다.
  2. hasUndefinedLabelstrue이면, true를 반환한다.
  3. ContainsUndefinedContinueTarget (StatementListItem, iterationSet, « »)의 결과를 반환한다.
IfStatement : if ( Expression ) Statement else Statement
  1. hasUndefinedLabels를 첫 번째 StatementiterationSet, « » 인수로 ContainsUndefinedContinueTarget의 결과로 한다.
  2. hasUndefinedLabelstrue이면, true를 반환한다.
  3. 두 번째 StatementiterationSet, « » 인수로 ContainsUndefinedContinueTarget의 결과를 반환한다.
IfStatement : if ( Expression ) Statement
  1. ContainsUndefinedContinueTarget (Statement, iterationSet, « »)의 결과를 반환한다.
DoWhileStatement : do Statement while ( Expression ) ;
  1. ContainsUndefinedContinueTarget (Statement, iterationSet, « »)의 결과를 반환한다.
WhileStatement : while ( Expression ) Statement
  1. ContainsUndefinedContinueTarget (Statement, iterationSet, « »)의 결과를 반환한다.
ForStatement : for ( Expressionopt ; Expressionopt ; Expressionopt ) Statement for ( var VariableDeclarationList ; Expressionopt ; Expressionopt ) Statement for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement
  1. ContainsUndefinedContinueTarget (Statement, iterationSet, « »)의 결과를 반환한다.
ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement for ( var ForBinding in Expression ) Statement for ( ForDeclaration in Expression ) Statement for ( LeftHandSideExpression of AssignmentExpression ) Statement for ( var ForBinding of AssignmentExpression ) Statement for ( ForDeclaration of AssignmentExpression ) Statement for await ( LeftHandSideExpression of AssignmentExpression ) Statement for await ( var ForBinding of AssignmentExpression ) Statement for await ( ForDeclaration of AssignmentExpression ) Statement
  1. ContainsUndefinedContinueTarget (Statement, iterationSet, « »)의 결과를 반환한다.
참고

이 절은 부록 B.3.5에 의해 확장된다.

ContinueStatement : continue ;
  1. false를 반환한다.
ContinueStatement : continue LabelIdentifier ;
  1. iterationSetStringValue(LabelIdentifier)가 포함되어 있지 않으면 true를 반환한다.
  2. false를 반환한다.
WithStatement : with ( Expression ) Statement
  1. ContainsUndefinedContinueTarget (Statement, iterationSet, « »)의 결과를 반환한다.
SwitchStatement : switch ( Expression ) CaseBlock
  1. ContainsUndefinedContinueTarget (CaseBlock, iterationSet, « »)의 결과를 반환한다.
CaseBlock : { }
  1. false를 반환한다.
CaseBlock : { CaseClausesopt DefaultClause CaseClausesopt }
  1. 첫 번째 CaseClauses가 있으면,
    1. 첫 번째 CaseClausesiterationSet, « » 인수로 ContainsUndefinedContinueTarget의 결과가 true이면 true를 반환한다.
  2. DefaultClauseiterationSet, « » 인수로 ContainsUndefinedContinueTarget의 결과가 true이면 true를 반환한다.
  3. 두 번째 CaseClauses가 없으면 false를 반환한다.
  4. 두 번째 CaseClausesiterationSet, « » 인수로 ContainsUndefinedContinueTarget의 결과를 반환한다.
CaseClauses : CaseClauses CaseClause
  1. hasUndefinedLabelsContainsUndefinedContinueTarget (CaseClauses, iterationSet, « »)의 결과로 한다.
  2. hasUndefinedLabelstrue이면, true를 반환한다.
  3. ContainsUndefinedContinueTarget (CaseClause, iterationSet, « »)의 결과를 반환한다.
CaseClause : case Expression : StatementListopt
  1. StatementList가 있으면 ContainsUndefinedContinueTarget (StatementList, iterationSet, « »)의 결과를 반환한다.
  2. false를 반환한다.
DefaultClause : default : StatementListopt
  1. StatementList가 있으면 ContainsUndefinedContinueTarget (StatementList, iterationSet, « »)의 결과를 반환한다.
  2. false를 반환한다.
LabelledStatement : LabelIdentifier : LabelledItem
  1. labelStringValue(LabelIdentifier)로 한다.
  2. newLabelSetlist-concatenation(labelSet, « label  »)로 한다.
  3. ContainsUndefinedContinueTarget (LabelledItem, iterationSet, newLabelSet)의 결과를 반환한다.
LabelledItem : FunctionDeclaration
  1. false를 반환한다.
TryStatement : try Block Catch
  1. hasUndefinedLabelsContainsUndefinedContinueTarget (Block, iterationSet, « »)의 결과로 한다.
  2. hasUndefinedLabelstrue이면, true를 반환한다.
  3. ContainsUndefinedContinueTarget (Catch, iterationSet, « »)의 결과를 반환한다.
TryStatement : try Block Finally
  1. hasUndefinedLabelsContainsUndefinedContinueTarget (Block, iterationSet, « »)의 결과로 한다.
  2. hasUndefinedLabelstrue이면, true를 반환한다.
  3. ContainsUndefinedContinueTarget (Finally, iterationSet, « »)의 결과를 반환한다.
TryStatement : try Block Catch Finally
  1. ContainsUndefinedContinueTarget (Block, iterationSet, « »)의 결과가 true이면 true를 반환한다.
  2. ContainsUndefinedContinueTarget (Catch, iterationSet, « »)의 결과가 true이면 true를 반환한다.
  3. ContainsUndefinedContinueTarget (Finally, iterationSet, « »)의 결과를 반환한다.
Catch : catch ( CatchParameter ) Block
  1. ContainsUndefinedContinueTarget (Block, iterationSet, « »)의 결과를 반환한다.
FunctionStatementList : [empty]
  1. false를 반환한다.
ClassStaticBlockStatementList : [empty]
  1. false를 반환한다.
ModuleItemList : ModuleItemList ModuleItem
  1. hasUndefinedLabelsContainsUndefinedContinueTarget (ModuleItemList, iterationSet, « »)의 결과로 한다.
  2. hasUndefinedLabelstrue이면, true를 반환한다.
  3. ContainsUndefinedContinueTarget (ModuleItem, iterationSet, « »)의 결과를 반환한다.
ModuleItem : ImportDeclaration ExportDeclaration
  1. false를 반환한다.

8.4 함수 이름 추론

8.4.1 정적 의미론: HasName

구문 지향 연산 HasName은 인수를 받지 않으며 불리언을 반환한다. 다음 생성 규칙에 대해 조각별로 정의된다:

PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList
  1. exprParenthesizedExpression로 한다. 이는 CoverCoverParenthesizedExpressionAndArrowParameterList이다.
  2. IsFunctionDefinitionexpr 값이 false이면, false를 반환한다.
  3. expr에 대한 HasName의 값을 반환한다.
FunctionExpression : function ( FormalParameters ) { FunctionBody } GeneratorExpression : function * ( FormalParameters ) { GeneratorBody } AsyncGeneratorExpression : async function * ( FormalParameters ) { AsyncGeneratorBody } AsyncFunctionExpression : async function ( FormalParameters ) { AsyncFunctionBody } ArrowFunction : ArrowParameters => ConciseBody AsyncArrowFunction : async AsyncArrowBindingIdentifier => AsyncConciseBody CoverCallExpressionAndAsyncArrowHead => AsyncConciseBody ClassExpression : class ClassTail
  1. false를 반환한다.
FunctionExpression : function BindingIdentifier ( FormalParameters ) { FunctionBody } GeneratorExpression : function * BindingIdentifier ( FormalParameters ) { GeneratorBody } AsyncGeneratorExpression : async function * BindingIdentifier ( FormalParameters ) { AsyncGeneratorBody } AsyncFunctionExpression : async function BindingIdentifier ( FormalParameters ) { AsyncFunctionBody } ClassExpression : class BindingIdentifier ClassTail
  1. true를 반환한다.

8.4.2 정적 의미론: IsFunctionDefinition

구문 지향 연산 IsFunctionDefinition은 인수를 받지 않으며 불리언을 반환한다. 다음 생성 규칙에 대해 조각별로 정의된다:

PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList
  1. exprParenthesizedExpression로 한다. 이는 CoverCoverParenthesizedExpressionAndArrowParameterList이다.
  2. expr에 대한 IsFunctionDefinition 값을 반환한다.
PrimaryExpression : this IdentifierReference Literal ArrayLiteral ObjectLiteral RegularExpressionLiteral TemplateLiteral MemberExpression : MemberExpression [ Expression ] MemberExpression . IdentifierName MemberExpression TemplateLiteral SuperProperty MetaProperty new MemberExpression Arguments MemberExpression . PrivateIdentifier NewExpression : new NewExpression LeftHandSideExpression : CallExpression OptionalExpression UpdateExpression : LeftHandSideExpression ++ LeftHandSideExpression -- ++ UnaryExpression -- UnaryExpression UnaryExpression : delete UnaryExpression void UnaryExpression typeof UnaryExpression + UnaryExpression - UnaryExpression ~ UnaryExpression ! UnaryExpression AwaitExpression ExponentiationExpression : UpdateExpression ** ExponentiationExpression MultiplicativeExpression : MultiplicativeExpression MultiplicativeOperator ExponentiationExpression AdditiveExpression : AdditiveExpression + MultiplicativeExpression AdditiveExpression - MultiplicativeExpression ShiftExpression : ShiftExpression << AdditiveExpression ShiftExpression >> AdditiveExpression ShiftExpression >>> AdditiveExpression RelationalExpression : RelationalExpression < ShiftExpression RelationalExpression > ShiftExpression RelationalExpression <= ShiftExpression RelationalExpression >= ShiftExpression RelationalExpression instanceof ShiftExpression RelationalExpression in ShiftExpression PrivateIdentifier in ShiftExpression EqualityExpression : EqualityExpression == RelationalExpression EqualityExpression != RelationalExpression EqualityExpression === RelationalExpression EqualityExpression !== RelationalExpression BitwiseANDExpression : BitwiseANDExpression & EqualityExpression BitwiseXORExpression : BitwiseXORExpression ^ BitwiseANDExpression BitwiseORExpression : BitwiseORExpression | BitwiseXORExpression LogicalANDExpression : LogicalANDExpression && BitwiseORExpression LogicalORExpression : LogicalORExpression || LogicalANDExpression CoalesceExpression : CoalesceExpressionHead ?? BitwiseORExpression ConditionalExpression : ShortCircuitExpression ? AssignmentExpression : AssignmentExpression AssignmentExpression : YieldExpression LeftHandSideExpression = AssignmentExpression LeftHandSideExpression AssignmentOperator AssignmentExpression LeftHandSideExpression &&= AssignmentExpression LeftHandSideExpression ||= AssignmentExpression LeftHandSideExpression ??= AssignmentExpression Expression : Expression , AssignmentExpression
  1. false를 반환한다.
AssignmentExpression : ArrowFunction AsyncArrowFunction FunctionExpression : function BindingIdentifieropt ( FormalParameters ) { FunctionBody } GeneratorExpression : function * BindingIdentifieropt ( FormalParameters ) { GeneratorBody } AsyncGeneratorExpression : async function * BindingIdentifieropt ( FormalParameters ) { AsyncGeneratorBody } AsyncFunctionExpression : async function BindingIdentifieropt ( FormalParameters ) { AsyncFunctionBody } ClassExpression : class BindingIdentifieropt ClassTail
  1. true를 반환한다.

8.4.3 정적 의미론: IsAnonymousFunctionDefinition ( expr )

추상 연산 IsAnonymousFunctionDefinition은 expr ( AssignmentExpression 파스 노드, Initializer 파스 노드, 또는 Expression 파스 노드 ) 인수를 받고 불리언을 반환한다. 이 연산은 인수가 이름을 바인딩하지 않는 함수 정의인지 판별한다. 호출 시 다음 단계를 수행한다:

  1. IsFunctionDefinition (expr)이 false이면, false를 반환한다.
  2. hasNameHasName(expr)로 한다.
  3. hasNametrue이면, false를 반환한다.
  4. true를 반환한다.

8.4.4 정적 의미론: IsIdentifierRef

구문 지향 연산 IsIdentifierRef는 인수를 받지 않으며 불리언을 반환한다. 다음 생성 규칙에 대해 조각별로 정의된다:

PrimaryExpression : IdentifierReference
  1. true를 반환한다.
PrimaryExpression : this Literal ArrayLiteral ObjectLiteral FunctionExpression ClassExpression GeneratorExpression AsyncFunctionExpression AsyncGeneratorExpression RegularExpressionLiteral TemplateLiteral CoverParenthesizedExpressionAndArrowParameterList MemberExpression : MemberExpression [ Expression ] MemberExpression . IdentifierName MemberExpression TemplateLiteral SuperProperty MetaProperty new MemberExpression Arguments MemberExpression . PrivateIdentifier NewExpression : new NewExpression LeftHandSideExpression : CallExpression OptionalExpression
  1. false를 반환한다.

8.4.5 실행 의미론: NamedEvaluation

구문 지향 연산 NamedEvaluation은 name ( 프로퍼티 키 또는 Private Name) 인수를 받고 정상 완료 값을 포함한 함수 객체 또는 급작스런 완료를 반환한다. 다음 생성 규칙에 대해 조각별로 정의된다:

PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList
  1. exprParenthesizedExpression로 한다. 이는 CoverCoverParenthesizedExpressionAndArrowParameterList이다.
  2. NamedEvaluation(expr, name)의 결과를 반환한다.
ParenthesizedExpression : ( Expression )
  1. Assert: IsAnonymousFunctionDefinition(Expression)이 true이다.
  2. NamedEvaluation(Expression, name)의 결과를 반환한다.
FunctionExpression : function ( FormalParameters ) { FunctionBody }
  1. InstantiateOrdinaryFunctionExpression (FunctionExpression, name)의 결과를 반환한다.
GeneratorExpression : function * ( FormalParameters ) { GeneratorBody }
  1. InstantiateGeneratorFunctionExpression (GeneratorExpression, name)의 결과를 반환한다.
AsyncGeneratorExpression : async function * ( FormalParameters ) { AsyncGeneratorBody }
  1. InstantiateAsyncGeneratorFunctionExpression (AsyncGeneratorExpression, name)의 결과를 반환한다.
AsyncFunctionExpression : async function ( FormalParameters ) { AsyncFunctionBody }
  1. InstantiateAsyncFunctionExpression (AsyncFunctionExpression, name)의 결과를 반환한다.
ArrowFunction : ArrowParameters => ConciseBody
  1. InstantiateArrowFunctionExpression (ArrowFunction, name)의 결과를 반환한다.
AsyncArrowFunction : async AsyncArrowBindingIdentifier => AsyncConciseBody CoverCallExpressionAndAsyncArrowHead => AsyncConciseBody
  1. InstantiateAsyncArrowFunctionExpression (AsyncArrowFunction, name)의 결과를 반환한다.
ClassExpression : class ClassTail
  1. value를 ? ClassDefinitionEvaluation(ClassTail, undefined, name)의 결과로 한다.
  2. value.[[SourceText]]source text matched by ClassExpression로 설정한다.
  3. value를 반환한다.

8.5 포함(Contains)

8.5.1 정적 의미: 포함(Contains)

구문 지향 연산 Contains는 symbol (문법 심볼)을 인자로 받아 Boolean을 반환한다.

아래에 명시되지 않은 이 명세의 모든 문법 생성 alternative는 암묵적으로 다음과 같은 기본 Contains 정의를 가진다:

  1. 파스 노드(Parse Node)의 각 자식 노드 child에 대해, 다음을 수행한다:
    1. childsymbol의 인스턴스라면, true를 반환한다.
    2. child가 비단말(nonterminal)의 인스턴스라면,
      1. containedchild Contains symbol의 결과로 둔다.
      2. containedtrue이면 true를 반환한다.
  2. false를 반환한다.
FunctionDeclaration : function BindingIdentifier ( FormalParameters ) { FunctionBody } function ( FormalParameters ) { FunctionBody } FunctionExpression : function BindingIdentifieropt ( FormalParameters ) { FunctionBody } GeneratorDeclaration : function * BindingIdentifier ( FormalParameters ) { GeneratorBody } function * ( FormalParameters ) { GeneratorBody } GeneratorExpression : function * BindingIdentifieropt ( FormalParameters ) { GeneratorBody } AsyncGeneratorDeclaration : async function * BindingIdentifier ( FormalParameters ) { AsyncGeneratorBody } async function * ( FormalParameters ) { AsyncGeneratorBody } AsyncGeneratorExpression : async function * BindingIdentifieropt ( FormalParameters ) { AsyncGeneratorBody } AsyncFunctionDeclaration : async function BindingIdentifier ( FormalParameters ) { AsyncFunctionBody } async function ( FormalParameters ) { AsyncFunctionBody } AsyncFunctionExpression : async function BindingIdentifieropt ( FormalParameters ) { AsyncFunctionBody }
  1. false를 반환한다.
참고 1

하위 구조에 의존하는 정적 의미 규칙들은 일반적으로 함수 정의 내부를 들여다보지 않는다.

ClassTail : ClassHeritageopt { ClassBody }
  1. symbolClassBody라면, true를 반환한다.
  2. symbolClassHeritage라면, 다음을 수행한다:
    1. ClassHeritage가 존재하면 true를, 그렇지 않으면 false를 반환한다.
  3. ClassHeritage가 존재하면, 다음을 수행한다:
    1. ClassHeritage Contains symboltrue라면 true를 반환한다.
  4. ClassBodyComputedPropertyContains 결과를 symbol 인자로 반환한다.
참고 2

하위 구조에 의존하는 정적 의미 규칙들은 일반적으로 PropertyName을 제외하고 클래스 바디 내부를 들여다보지 않는다.

ClassStaticBlock : static { ClassStaticBlockBody }
  1. false를 반환한다.
참고 3

하위 구조에 의존하는 정적 의미 규칙들은 static 초기화 블록 내부를 일반적으로 들여다보지 않는다.

ArrowFunction : ArrowParameters => ConciseBody
  1. symbolNewTarget, SuperProperty, SuperCall, super, 또는 this 중 하나가 아니라면 false를 반환한다.
  2. ArrowParameters Contains symboltrue라면, true를 반환한다.
  3. ConciseBody Contains symbol의 결과를 반환한다.
ArrowParameters : CoverParenthesizedExpressionAndArrowParameterList
  1. formalsArrowFormalParameters로 두는데, 이는 coveredCoverParenthesizedExpressionAndArrowParameterList에서 나온다.
  2. formals Contains symbol의 결과를 반환한다.
AsyncArrowFunction : async AsyncArrowBindingIdentifier => AsyncConciseBody
  1. symbolNewTarget, SuperProperty, SuperCall, super, 또는 this 중 하나가 아니라면 false를 반환한다.
  2. AsyncConciseBody Contains symbol의 결과를 반환한다.
AsyncArrowFunction : CoverCallExpressionAndAsyncArrowHead => AsyncConciseBody
  1. symbolNewTarget, SuperProperty, SuperCall, super, 또는 this 중 하나가 아니라면 false를 반환한다.
  2. headAsyncArrowHead로 두는데, 이는 coveredCoverCallExpressionAndAsyncArrowHead에서 나온다.
  3. head Contains symboltrue라면, true를 반환한다.
  4. AsyncConciseBody Contains symbol의 결과를 반환한다.
참고 4

Contains는 ArrowFunction 또는 AsyncArrowFunction 내에서 new.target, this, super 사용을 감지하는 데 사용된다.

PropertyDefinition : MethodDefinition
  1. symbolMethodDefinition라면 true를 반환한다.
  2. MethodDefinitionComputedPropertyContains 결과를 symbol 인자로 반환한다.
LiteralPropertyName : IdentifierName
  1. false를 반환한다.
MemberExpression : MemberExpression . IdentifierName
  1. MemberExpression Contains symboltrue라면, true를 반환한다.
  2. false를 반환한다.
SuperProperty : super . IdentifierName
  1. symbolReservedWord super라면 true를 반환한다.
  2. false를 반환한다.
CallExpression : CallExpression . IdentifierName
  1. CallExpression Contains symboltrue라면, true를 반환한다.
  2. false를 반환한다.
OptionalChain : ?. IdentifierName
  1. false를 반환한다.
OptionalChain : OptionalChain . IdentifierName
  1. OptionalChain Contains symboltrue라면, true를 반환한다.
  2. false를 반환한다.

8.5.2 정적 의미: ComputedPropertyContains

구문 지향 연산 ComputedPropertyContains는 symbol (문법 심볼)을 인자로 받아 Boolean을 반환한다. 이 연산은 아래의 생성 규칙들에 대해 부분적으로 정의된다.

ClassElementName : PrivateIdentifier PropertyName : LiteralPropertyName
  1. false를 반환한다.
PropertyName : ComputedPropertyName
  1. ComputedPropertyName Contains symbol의 결과를 반환한다.
MethodDefinition : ClassElementName ( UniqueFormalParameters ) { FunctionBody } get ClassElementName ( ) { FunctionBody } set ClassElementName ( PropertySetParameterList ) { FunctionBody }
  1. ClassElementNameComputedPropertyContains 결과를 symbol 인자로 반환한다.
GeneratorMethod : * ClassElementName ( UniqueFormalParameters ) { GeneratorBody }
  1. ClassElementNameComputedPropertyContains 결과를 symbol 인자로 반환한다.
AsyncGeneratorMethod : async * ClassElementName ( UniqueFormalParameters ) { AsyncGeneratorBody }
  1. ClassElementNameComputedPropertyContains 결과를 symbol 인자로 반환한다.
ClassElementList : ClassElementList ClassElement
  1. inListClassElementListComputedPropertyContains 결과로 symbol 인자를 사용하여 구한다.
  2. inListtrue라면, true를 반환한다.
  3. ClassElementComputedPropertyContains 결과를 symbol 인자로 반환한다.
ClassElement : ClassStaticBlock
  1. false를 반환한다.
ClassElement : ;
  1. false를 반환한다.
AsyncMethod : async ClassElementName ( UniqueFormalParameters ) { AsyncFunctionBody }
  1. ClassElementNameComputedPropertyContains 결과를 symbol 인자로 반환한다.
FieldDefinition : ClassElementName Initializeropt
  1. ClassElementNameComputedPropertyContains 결과를 symbol 인자로 반환한다.

8.6 기타

이 연산들은 명세 전반의 여러 곳에서 사용됩니다.

8.6.1 런타임 의미론: InstantiateFunctionObject

구문 지시 연산 InstantiateFunctionObject는 env (Environment Record)와 privateEnv (PrivateEnvironment Record 또는 null) 인자를 받고, ECMAScript 함수 객체를 반환합니다. 이는 다음 생성 규칙에 따라 부분적으로 정의됩니다:

FunctionDeclaration : function BindingIdentifier ( FormalParameters ) { FunctionBody } function ( FormalParameters ) { FunctionBody }
  1. InstantiateOrdinaryFunctionObjectFunctionDeclaration에 대해 envprivateEnv 인자를 넣어 호출한 결과를 반환한다.
GeneratorDeclaration : function * BindingIdentifier ( FormalParameters ) { GeneratorBody } function * ( FormalParameters ) { GeneratorBody }
  1. InstantiateGeneratorFunctionObjectGeneratorDeclaration에 대해 envprivateEnv 인자를 넣어 호출한 결과를 반환한다.
AsyncGeneratorDeclaration : async function * BindingIdentifier ( FormalParameters ) { AsyncGeneratorBody } async function * ( FormalParameters ) { AsyncGeneratorBody }
  1. InstantiateAsyncGeneratorFunctionObjectAsyncGeneratorDeclaration 에 대해 envprivateEnv 인자를 넣어 호출한 결과를 반환한다.
AsyncFunctionDeclaration : async function BindingIdentifier ( FormalParameters ) { AsyncFunctionBody } async function ( FormalParameters ) { AsyncFunctionBody }
  1. InstantiateAsyncFunctionObjectAsyncFunctionDeclaration에 대해 envprivateEnv 인자를 넣어 호출한 결과를 반환한다.

8.6.2 런타임 의미론: BindingInitialization

구문 지시 연산 BindingInitialization은 value (ECMAScript 언어 값)과 environment (Environment Record 또는 undefined) 인자를 받고, unused를 포함하는 정상 완료 또는 비정상 완료 중 하나를 반환한다.

참고

environmentundefined가 전달되는 것은 초기화 값을 할당할 때 PutValue 연산을 사용해야 함을 나타낸다. 이는 var 문과 일부 비엄격 함수의 명시적 매개변수 목록(자세한 내용은 10.2.11 참고)에 해당한다. 이런 경우 렉시컬 바인딩이 호이스팅되고, 초기화식이 평가되기 전에 미리 초기화된다.

다음 생성 규칙에 따라 부분적으로 정의된다:

BindingIdentifier : Identifier
  1. nameStringValue of Identifier로 둔다.
  2. InitializeBoundName(name, value, environment)를 반환한다.
BindingIdentifier : yield
  1. InitializeBoundName("yield", value, environment)를 반환한다.
BindingIdentifier : await
  1. InitializeBoundName("await", value, environment)를 반환한다.
BindingPattern : ObjectBindingPattern
  1. RequireObjectCoercible(value)를 수행한다.
  2. BindingInitialization of ObjectBindingPatternvalue, environment 인자로 호출한 결과를 반환한다.
BindingPattern : ArrayBindingPattern
  1. iteratorRecord를 ? GetIterator(value, sync)로 둔다.
  2. resultCompletion(IteratorBindingInitialization of ArrayBindingPatterniteratorRecord, environment 인자로 호출)로 둔다.
  3. 만약 iteratorRecord.[[Done]]false라면, ? IteratorClose(iteratorRecord, result)를 반환한다.
  4. result를 반환한다.
ObjectBindingPattern : { }
  1. unused를 반환한다.
ObjectBindingPattern : { BindingPropertyList } { BindingPropertyList , }
  1. PropertyBindingInitialization of BindingPropertyListvalue, environment 인자로 호출한다.
  2. unused를 반환한다.
ObjectBindingPattern : { BindingRestProperty }
  1. excludedNames를 새로운 빈 List로 둔다.
  2. RestBindingInitialization of BindingRestPropertyvalue, environment, excludedNames 인자로 호출한 결과를 반환한다.
ObjectBindingPattern : { BindingPropertyList , BindingRestProperty }
  1. excludedNames를 ? PropertyBindingInitialization of BindingPropertyListvalue, environment 인자로 호출한 결과로 둔다.
  2. RestBindingInitialization of BindingRestPropertyvalue, environment, excludedNames 인자로 호출한 결과를 반환한다.

8.6.2.1 InitializeBoundName ( name, value, environment )

추상 연산 InitializeBoundName은 name (문자열), value (ECMAScript 언어 값), 그리고 environment (Environment Record 또는 undefined) 인자를 받고, unused를 포함하는 정상 완료 또는 비정상 완료 중 하나를 반환한다. 다음 단계를 수행한다:

  1. 만약 environmentundefined가 아니라면,
    1. environment.InitializeBinding(name, value)을 수행한다.
    2. unused를 반환한다.
  2. 그 외의 경우,
    1. lhs를 ? ResolveBinding(name)로 둔다.
    2. PutValue(lhs, value)를 반환한다.

8.6.3 런타임 의미론: IteratorBindingInitialization

구문 지시 연산 IteratorBindingInitialization은 iteratorRecord (Iterator Record 타입)와 environment (Environment Record 또는 undefined) 인자를 받고, unused를 포함하는 정상 완료 또는 비정상 완료 중 하나를 반환한다.

참고

environmentundefined가 전달될 경우, 초기화 값 할당에 PutValue 연산을 사용해야 함을 나타낸다. 이는 비엄격 함수의 명시적 매개변수 목록에 해당한다. 이 경우 동일한 이름의 매개변수가 여러 개 있을 수 있으므로, 명시적 매개변수 바인딩을 미리 초기화한다.

다음 생성 규칙에 따라 부분적으로 정의된다:

ArrayBindingPattern : [ ]
  1. unused를 반환한다.
ArrayBindingPattern : [ Elision ]
  1. IteratorDestructuringAssignmentEvaluation of ElisioniteratorRecord 인자를 넣어 호출한 결과를 반환한다.
ArrayBindingPattern : [ Elisionopt BindingRestElement ]
  1. 만약 Elision이 존재한다면,
    1. IteratorDestructuringAssignmentEvaluation of ElisioniteratorRecord 인자를 넣어 호출한다.
  2. IteratorBindingInitialization of BindingRestElementiteratorRecord, environment 인자를 넣어 호출한 결과를 반환한다.
ArrayBindingPattern : [ BindingElementList , Elision ]
  1. IteratorBindingInitialization of BindingElementListiteratorRecord, environment 인자를 넣어 호출한다.
  2. IteratorDestructuringAssignmentEvaluation of ElisioniteratorRecord 인자를 넣어 호출한 결과를 반환한다.
ArrayBindingPattern : [ BindingElementList , Elisionopt BindingRestElement ]
  1. IteratorBindingInitialization of BindingElementListiteratorRecord, environment 인자를 넣어 호출한다.
  2. 만약 Elision이 존재한다면,
    1. IteratorDestructuringAssignmentEvaluation of ElisioniteratorRecord 인자를 넣어 호출한다.
  3. IteratorBindingInitialization of BindingRestElementiteratorRecord, environment 인자를 넣어 호출한 결과를 반환한다.
BindingElementList : BindingElementList , BindingElisionElement
  1. IteratorBindingInitialization of BindingElementListiteratorRecord, environment 인자를 넣어 호출한다.
  2. IteratorBindingInitialization of BindingElisionElementiteratorRecord, environment 인자를 넣어 호출한 결과를 반환한다.
BindingElisionElement : Elision BindingElement
  1. IteratorDestructuringAssignmentEvaluation of ElisioniteratorRecord 인자를 넣어 호출한다.
  2. IteratorBindingInitialization of BindingElementiteratorRecord, environment 인자를 넣어 호출한 결과를 반환한다.
SingleNameBinding : BindingIdentifier Initializeropt
  1. bindingIdStringValue of BindingIdentifier로 둔다.
  2. lhs를 ? ResolveBinding(bindingId, environment)로 둔다.
  3. vundefined로 둔다.
  4. 만약 iteratorRecord.[[Done]]false라면,
    1. next를 ? IteratorStepValue(iteratorRecord)로 둔다.
    2. 만약 nextdone이 아니라면,
      1. vnext를 할당한다.
  5. 만약 Initializer가 존재하고 vundefined라면,
    1. 만약 IsAnonymousFunctionDefinition(Initializer)가 true라면,
      1. v에 ? NamedEvaluation of InitializerbindingId 인자로 호출한 결과를 할당한다.
    2. 그 외의 경우,
      1. defaultValue를 ? Evaluation of Initializer로 둔다.
      2. v에 ? GetValue(defaultValue)를 할당한다.
  6. 만약 environmentundefined라면, ? PutValue(lhs, v)를 반환한다.
  7. InitializeReferencedBinding(lhs, v)를 반환한다.
BindingElement : BindingPattern Initializeropt
  1. vundefined로 둔다.
  2. 만약 iteratorRecord.[[Done]]false라면,
    1. next를 ? IteratorStepValue(iteratorRecord)로 둔다.
    2. 만약 nextdone이 아니라면,
      1. vnext를 할당한다.
  3. 만약 Initializer가 존재하고 vundefined라면,
    1. defaultValue를 ? Evaluation of Initializer로 둔다.
    2. v에 ? GetValue(defaultValue)를 할당한다.
  4. BindingInitialization of BindingPatternv, environment 인자를 넣어 호출한 결과를 반환한다.
BindingRestElement : ... BindingIdentifier
  1. lhs를 ? ResolveBinding(StringValue of BindingIdentifier, environment)로 둔다.
  2. A를 ! ArrayCreate(0)로 둔다.
  3. n을 0으로 둔다.
  4. 반복,
    1. nextdone으로 둔다.
    2. 만약 iteratorRecord.[[Done]]false라면,
      1. next를 ? IteratorStepValue(iteratorRecord)로 둔다.
    3. 만약 nextdone이라면,
      1. 만약 environmentundefined라면, ? PutValue(lhs, A)를 반환한다.
      2. InitializeReferencedBinding(lhs, A)를 반환한다.
    4. CreateDataPropertyOrThrow(A, ! ToString(𝔽(n)), next))를 수행한다.
    5. nn + 1로 갱신한다.
BindingRestElement : ... BindingPattern
  1. A를 ! ArrayCreate(0)로 둔다.
  2. n을 0으로 둔다.
  3. 반복,
    1. nextdone으로 둔다.
    2. 만약 iteratorRecord.[[Done]]false라면,
      1. next를 ? IteratorStepValue(iteratorRecord)로 둔다.
    3. 만약 nextdone이라면,
      1. BindingInitialization of BindingPatternA, environment 인자를 넣어 호출한 결과를 반환한다.
    4. CreateDataPropertyOrThrow(A, ! ToString(𝔽(n)), next))를 수행한다.
    5. nn + 1로 갱신한다.
FormalParameters : [empty]
  1. unused를 반환한다.
FormalParameters : FormalParameterList , FunctionRestParameter
  1. IteratorBindingInitialization of FormalParameterListiteratorRecord, environment 인자를 넣어 호출한다.
  2. IteratorBindingInitialization of FunctionRestParameteriteratorRecord, environment 인자를 넣어 호출한 결과를 반환한다.
FormalParameterList : FormalParameterList , FormalParameter
  1. IteratorBindingInitialization of FormalParameterListiteratorRecord, environment 인자를 넣어 호출한다.
  2. IteratorBindingInitialization of FormalParameteriteratorRecord, environment 인자를 넣어 호출한 결과를 반환한다.
ArrowParameters : BindingIdentifier
  1. vundefined로 둔다.
  2. Assert: iteratorRecord.[[Done]]false임을 보장한다.
  3. next를 ? IteratorStepValue(iteratorRecord)로 둔다.
  4. 만약 nextdone이 아니라면,
    1. vnext를 할당한다.
  5. BindingInitialization of BindingIdentifierv, environment 인자를 넣어 호출한 결과를 반환한다.
ArrowParameters : CoverParenthesizedExpressionAndArrowParameterList
  1. formalsArrowFormalParameters로 두는데, 이는 covered by CoverParenthesizedExpressionAndArrowParameterList에 해당한다.
  2. IteratorBindingInitialization of formalsiteratorRecord, environment 인자를 넣어 호출한 결과를 반환한다.
AsyncArrowBindingIdentifier : BindingIdentifier
  1. vundefined로 둔다.
  2. Assert: iteratorRecord.[[Done]]false임을 보장한다.
  3. next를 ? IteratorStepValue(iteratorRecord)로 둔다.
  4. 만약 nextdone이 아니라면,
    1. vnext를 할당한다.
  5. BindingInitialization of BindingIdentifierv, environment 인자를 넣어 호출한 결과를 반환한다.

8.6.4 정적 의미론: AssignmentTargetType

구문 지시 연산 AssignmentTargetType은 인자를 받지 않으며, simple, web-compat, 또는 invalid 중 하나를 반환한다. 이는 다음 생성 규칙에 따라 부분적으로 정의된다:

IdentifierReference : Identifier
  1. 만약 IsStrict(이 IdentifierReference)가 true이고, StringValue of Identifier"eval" 또는 "arguments"인 경우, invalid를 반환한다.
  2. simple를 반환한다.
IdentifierReference : yield await CallExpression : CallExpression [ Expression ] CallExpression . IdentifierName CallExpression . PrivateIdentifier MemberExpression : MemberExpression [ Expression ] MemberExpression . IdentifierName SuperProperty MemberExpression . PrivateIdentifier
  1. simple를 반환한다.
PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList
  1. exprParenthesizedExpression로 두는데, 이는 covered by CoverParenthesizedExpressionAndArrowParameterList에 해당한다.
  2. exprAssignmentTargetType을 반환한다.
CallExpression : CoverCallExpressionAndAsyncArrowHead CallExpression Arguments
  1. 만약 host가 웹 브라우저이거나 함수 호출 할당 대상에 대한 런타임 오류를 지원하고, IsStrict(이 CallExpression)가 false라면,
    1. web-compat를 반환한다.
  2. invalid를 반환한다.
PrimaryExpression : this Literal ArrayLiteral ObjectLiteral FunctionExpression ClassExpression GeneratorExpression AsyncFunctionExpression AsyncGeneratorExpression RegularExpressionLiteral TemplateLiteral CallExpression : SuperCall ImportCall CallExpression TemplateLiteral NewExpression : new NewExpression MemberExpression : MemberExpression TemplateLiteral new MemberExpression Arguments NewTarget : new . target ImportMeta : import . meta LeftHandSideExpression : OptionalExpression UpdateExpression : LeftHandSideExpression ++ LeftHandSideExpression -- ++ UnaryExpression -- UnaryExpression UnaryExpression : delete UnaryExpression void UnaryExpression typeof UnaryExpression + UnaryExpression - UnaryExpression ~ UnaryExpression ! UnaryExpression AwaitExpression ExponentiationExpression : UpdateExpression ** ExponentiationExpression MultiplicativeExpression : MultiplicativeExpression MultiplicativeOperator ExponentiationExpression AdditiveExpression : AdditiveExpression + MultiplicativeExpression AdditiveExpression - MultiplicativeExpression ShiftExpression : ShiftExpression << AdditiveExpression ShiftExpression >> AdditiveExpression ShiftExpression >>> AdditiveExpression RelationalExpression : RelationalExpression < ShiftExpression RelationalExpression > ShiftExpression RelationalExpression <= ShiftExpression RelationalExpression >= ShiftExpression RelationalExpression instanceof ShiftExpression RelationalExpression in ShiftExpression PrivateIdentifier in ShiftExpression EqualityExpression : EqualityExpression == RelationalExpression EqualityExpression != RelationalExpression EqualityExpression === RelationalExpression EqualityExpression !== RelationalExpression BitwiseANDExpression : BitwiseANDExpression & EqualityExpression BitwiseXORExpression : BitwiseXORExpression ^ BitwiseANDExpression BitwiseORExpression : BitwiseORExpression | BitwiseXORExpression LogicalANDExpression : LogicalANDExpression && BitwiseORExpression LogicalORExpression : LogicalORExpression || LogicalANDExpression CoalesceExpression : CoalesceExpressionHead ?? BitwiseORExpression ConditionalExpression : ShortCircuitExpression ? AssignmentExpression : AssignmentExpression AssignmentExpression : YieldExpression ArrowFunction AsyncArrowFunction LeftHandSideExpression = AssignmentExpression LeftHandSideExpression AssignmentOperator AssignmentExpression LeftHandSideExpression &&= AssignmentExpression LeftHandSideExpression ||= AssignmentExpression LeftHandSideExpression ??= AssignmentExpression Expression : Expression , AssignmentExpression
  1. invalid를 반환한다.

8.6.5 정적 의미론: PropName

구문 지시 연산 PropName은 인자를 받지 않으며, 문자열 또는 empty를 반환한다. 이는 다음 생성 규칙에 따라 부분적으로 정의된다:

PropertyDefinition : IdentifierReference
  1. IdentifierReferenceStringValue를 반환한다.
PropertyDefinition : ... AssignmentExpression
  1. empty를 반환한다.
PropertyDefinition : PropertyName : AssignmentExpression
  1. PropertyNamePropName을 반환한다.
LiteralPropertyName : IdentifierName AttributeKey : IdentifierName
  1. IdentifierNameStringValue를 반환한다.
LiteralPropertyName : StringLiteral AttributeKey : StringLiteral
  1. StringLiteralSV를 반환한다.
LiteralPropertyName : NumericLiteral
  1. nbrNumericLiteralNumericValue로 둔다.
  2. ToString(nbr)을 반환한다.
ComputedPropertyName : [ AssignmentExpression ]
  1. empty를 반환한다.
MethodDefinition : ClassElementName ( UniqueFormalParameters ) { FunctionBody } get ClassElementName ( ) { FunctionBody } set ClassElementName ( PropertySetParameterList ) { FunctionBody }
  1. ClassElementNamePropName을 반환한다.
GeneratorMethod : * ClassElementName ( UniqueFormalParameters ) { GeneratorBody }
  1. ClassElementNamePropName을 반환한다.
AsyncGeneratorMethod : async * ClassElementName ( UniqueFormalParameters ) { AsyncGeneratorBody }
  1. ClassElementNamePropName을 반환한다.
ClassElement : ClassStaticBlock
  1. empty를 반환한다.
ClassElement : ;
  1. empty를 반환한다.
AsyncMethod : async ClassElementName ( UniqueFormalParameters ) { AsyncFunctionBody }
  1. ClassElementNamePropName을 반환한다.
FieldDefinition : ClassElementName Initializeropt
  1. ClassElementNamePropName을 반환한다.
ClassElementName : PrivateIdentifier
  1. empty를 반환한다.

9 실행 가능한 코드와 실행 컨텍스트

9.1 환경 레코드

Environment Record는 ECMAScript 코드의 렉시컬 중첩 구조에 기반하여 Identifier들을 특정 변수와 함수에 연관시키기 위해 사용되는 명세 타입입니다. 보통 환경 레코드는 FunctionDeclaration, BlockStatement, 또는 Catch 절과 같이 ECMAScript 코드의 특정 구문 구조와 연결됩니다. 이와 같은 코드가 평가될 때마다, 해당 코드가 생성하는 식별자 바인딩을 기록하기 위해 새로운 환경 레코드가 생성됩니다.

모든 환경 레코드는 [[OuterEnv]] 필드를 가지며, 이 값은 null이거나 외부 환경 레코드를 참조합니다. 이 필드는 환경 레코드 값들의 논리적 중첩 구조를 모델링하는 데 사용됩니다. (내부) 환경 레코드의 외부 참조는 논리적으로 그 내부 환경 레코드를 둘러싸는 환경 레코드를 참조합니다. 외부 환경 레코드는 물론 그 자체로 또 다른 외부 환경 레코드를 가질 수 있습니다. 하나의 환경 레코드는 여러 내부 환경 레코드의 외부 환경이 될 수 있습니다. 예를 들어, FunctionDeclaration이 두 개의 중첩된 FunctionDeclaration을 포함한다면, 각 중첩 함수의 환경 레코드는 현재 평가 중인 외부 함수의 환경 레코드를 외부 환경 레코드로 갖게 됩니다.

환경 레코드는 오직 명세상의 메커니즘일 뿐이며, ECMAScript 구현의 어떤 특정 산출물과 반드시 대응할 필요는 없습니다. ECMAScript 프로그램이 이러한 값을 직접적으로 접근하거나 조작하는 것은 불가능합니다.

9.1.1 환경 레코드 타입 계층

환경 레코드Environment Record가 추상 클래스이고, 세 가지 구체적 하위 클래스를 가지는 단순한 객체 지향 계층으로 생각할 수 있습니다: 선언적 환경 레코드, 객체 환경 레코드, 그리고 전역 환경 레코드. 함수 환경 레코드모듈 환경 레코드선언적 환경 레코드의 하위 클래스입니다.

  • Environment Record (추상)

    • 선언적 환경 레코드FunctionDeclaration, VariableDeclaration, Catch 절 등과 같이, 식별자 바인딩을 ECMAScript 언어 값에 직접적으로 연결하는 ECMAScript 언어 구문 요소의 효과를 정의하는 데 사용됩니다.

      • 함수 환경 레코드는 ECMAScript 함수 객체의 호출에 대응하며, 해당 함수 내의 최상위 선언에 대한 바인딩을 포함합니다. 또한 새로운 this 바인딩을 설정할 수 있습니다. 그리고 super 메서드 호출을 지원하기 위한 상태도 캡처합니다.

      • 모듈 환경 레코드Module의 최상위 선언에 대한 바인딩을 포함합니다. 또한 Module이 명시적으로 가져온 바인딩도 포함합니다. 그 [[OuterEnv]]전역 환경 레코드입니다.

    • 객체 환경 레코드WithStatement 등과 같이 식별자 바인딩을 어떤 객체의 프로퍼티와 연결하는 ECMAScript 요소의 효과를 정의하는 데 사용됩니다.

    • 전역 환경 레코드Script의 전역 선언에 사용됩니다. 이 레코드는 외부 환경을 가지지 않으며, 그 [[OuterEnv]]null입니다. 미리 식별자 바인딩이 채워져 있을 수 있으며, 글로벌 객체와 연관되어 있어, 그 프로퍼티들이 전역 환경의 일부 식별자 바인딩을 제공합니다. ECMAScript 코드가 실행됨에 따라 글로벌 객체에 프로퍼티가 추가될 수 있고, 초기 프로퍼티들이 수정될 수도 있습니다.

환경 레코드 추상 클래스에는 표 16에 정의된 추상 명세 메서드가 포함되어 있습니다. 이 추상 메서드들은 각 구체적 하위 클래스마다 서로 다른 구체적 알고리즘을 가집니다.

표 16: 환경 레코드의 추상 메서드
메서드 목적
HasBinding(N) 환경 레코드가 문자열 값 N에 대한 바인딩을 가지고 있는지 확인합니다. 가지고 있다면 true를, 아니라면 false를 반환합니다.
CreateMutableBinding(N, D) 환경 레코드에 새로운(아직 초기화되지 않은) 변경 가능한 바인딩을 생성합니다. 문자열 값 N은 바인딩될 이름의 텍스트입니다. 불리언 인자 Dtrue라면, 이 바인딩은 이후 삭제될 수 있습니다.
CreateImmutableBinding(N, S) 환경 레코드에 새로운(아직 초기화되지 않은) 변경 불가능한 바인딩을 생성합니다. 문자열 값 N은 바인딩될 이름의 텍스트입니다. Strue라면, 초기화 후 값을 설정하려는 시도는 엄격 모드 여부와 관계없이 항상 예외를 발생시킵니다.
InitializeBinding(N, V) 환경 레코드에 이미 존재하지만 아직 초기화되지 않은 바인딩의 값을 설정합니다. 문자열 값 N은 바인딩될 이름의 텍스트입니다. V는 바인딩에 대한 값이며, ECMAScript 언어 타입의 값입니다.
SetMutableBinding(N, V, S) 환경 레코드에 이미 존재하는 변경 가능한 바인딩의 값을 설정합니다. 문자열 값 N은 바인딩될 이름의 텍스트입니다. V는 바인딩에 대한 값이며, ECMAScript 언어 타입의 값일 수 있습니다. S불리언 플래그입니다. Strue이며 바인딩에 값을 설정할 수 없으면 TypeError 예외를 발생시킵니다.
GetBindingValue(N, S) 환경 레코드에서 이미 존재하는 바인딩의 값을 반환합니다. 문자열 값 N은 바인딩될 이름의 텍스트입니다. S엄격 모드 코드에서 시작되었거나 엄격 모드 참조语 의미가 요구되는 참조를 식별하는 데 사용됩니다. Strue이고 바인딩이 존재하지 않으면 ReferenceError 예외를 발생시킵니다. 바인딩이 존재하지만 초기화되지 않았다면 S의 값과 상관없이 ReferenceError가 발생합니다.
DeleteBinding(N) 환경 레코드에서 바인딩을 삭제합니다. 문자열 값 N은 바인딩될 이름의 텍스트입니다. N에 대한 바인딩이 존재하면 해당 바인딩을 제거하고 true를 반환합니다. 바인딩이 존재하나 삭제할 수 없는 경우 false를 반환합니다. 바인딩이 존재하지 않으면 true를 반환합니다.
HasThisBinding() 환경 레코드this 바인딩을 설정하는지 확인합니다. 그렇다면 true, 아니라면 false를 반환합니다.
HasSuperBinding() 환경 레코드super 메서드 바인딩을 설정하는지 확인합니다. 그렇다면 true, 아니라면 false를 반환합니다. true를 반환한다면 환경 레코드함수 환경 레코드임을 의미하지만, 그 역은 성립하지 않습니다.
WithBaseObject() 환경 레코드with 문과 연관되어 있다면, with 객체를 반환합니다. 그렇지 않으면 undefined를 반환합니다.

9.1.1.1 선언적 환경 레코드

선언적 환경 레코드는 변수, 상수, let, class, module, import, 그리고/또는 함수 선언을 포함하는 ECMAScript 프로그램 스코프와 연관되어 있습니다. 선언적 환경 레코드는 그 스코프 내에 포함된 선언들이 정의하는 식별자 집합을 바인딩합니다.

9.1.1.1.1 HasBinding ( N )

선언적 환경 레코드 envRec의 HasBinding 구체 메서드는 N (문자열)을 인자로 받아 불리언을 포함하는 정상 완료를 반환합니다. 이 메서드는 인자로 받은 식별자가 레코드에 바인딩된 식별자 중 하나인지 판단합니다. 호출 시 다음 단계를 수행합니다:

  1. envRecN에 대한 바인딩을 가지고 있다면 true를 반환한다.
  2. false를 반환한다.

9.1.1.1.2 CreateMutableBinding ( N, D )

선언적 환경 레코드 envRec의 CreateMutableBinding 구체 메서드는 N (문자열)과 D (불리언)를 인자로 받아 unused를 포함하는 정상 완료를 반환합니다. 이름 N에 대해 초기화되지 않은 새로운 변경 가능한 바인딩을 생성합니다. 이 환경 레코드 내에 N에 대한 바인딩이 이미 존재해서는 안 됩니다. Dtrue이면, 새로 생성된 바인딩은 삭제 대상임이 표시됩니다. 호출 시 다음 단계를 수행합니다:

  1. Assert: envRec가 이미 N에 대한 바인딩을 가지고 있지 않음을 보장한다.
  2. envRec에 대해 N에 대한 변경 가능한 바인딩을 생성하고, 초기화되지 않았음을 기록한다. Dtrue이면, 새로 생성된 바인딩이 이후 DeleteBinding 호출로 삭제될 수 있음을 기록한다.
  3. unused를 반환한다.

9.1.1.1.3 CreateImmutableBinding ( N, S )

선언적 환경 레코드 envRec의 CreateImmutableBinding 구체 메서드는 N (문자열)과 S (불리언)를 인자로 받아 unused를 포함하는 정상 완료를 반환합니다. 이름 N에 대해 초기화되지 않은 새로운 변경 불가능한 바인딩을 생성합니다. 이 환경 레코드 내에 N에 대한 바인딩이 이미 존재해서는 안 됩니다. Strue이면, 새로 생성된 바인딩이 strict 바인딩임을 표시합니다. 호출 시 다음 단계를 수행합니다:

  1. Assert: envRec가 이미 N에 대한 바인딩을 가지고 있지 않음을 보장한다.
  2. envRec에 대해 N에 대한 변경 불가능한 바인딩을 생성하고, 초기화되지 않았음을 기록한다. Strue이면, 새로 생성된 바인딩이 strict 바인딩임을 기록한다.
  3. unused를 반환한다.

9.1.1.1.4 InitializeBinding ( N, V )

선언적 환경 레코드 envRec의 InitializeBinding 구체 메서드는 N (문자열)과 V (ECMAScript 언어 값)를 인자로 받아 unused를 포함하는 정상 완료를 반환합니다. 이 메서드는 이름이 N인 식별자의 현재 바인딩의 값을 V로 설정합니다. N에 대한 초기화되지 않은 바인딩이 이미 존재해야 합니다. 호출 시 다음 단계를 수행합니다:

  1. Assert: envRecN에 대한 초기화되지 않은 바인딩이 존재함을 보장한다.
  2. envRecN에 대한 바인딩 값을 V로 설정한다.
  3. envRecN에 대한 바인딩이 초기화되었음을 기록한다.
  4. unused를 반환한다.

9.1.1.1.5 SetMutableBinding ( N, V, S )

선언적 환경 레코드 envRec의 SetMutableBinding 구체 메서드는 N (문자열), V (ECMAScript 언어 값), S (불리언)를 인자로 받아 unused를 포함하는 정상 완료 또는 throw completion을 반환합니다. 이 메서드는 이름이 N인 식별자의 현재 바인딩의 값을 V로 변경하려고 시도합니다. N에 대한 바인딩이 보통 이미 존재하지만, 드물게 존재하지 않을 수도 있습니다. 바인딩이 변경 불가능한 경우 Strue이면 TypeError를 발생시킵니다. 호출 시 다음 단계를 수행합니다:

  1. 만약 envRecN에 대한 바인딩이 존재하지 않는다면,
    1. Strue이면 ReferenceError 예외를 발생시킨다.
    2. envRec.CreateMutableBinding(N, true)을 수행한다.
    3. envRec.InitializeBinding(N, V)을 수행한다.
    4. unused를 반환한다.
  2. envRecN에 대한 바인딩이 strict 바인딩이라면, Strue로 설정한다.
  3. envRecN에 대한 바인딩이 아직 초기화되지 않았다면,
    1. ReferenceError 예외를 발생시킨다.
  4. 그 외에 envRecN에 대한 바인딩이 변경 가능한 바인딩이라면,
    1. 그 값을 V로 변경한다.
  5. 그 외의 경우,
    1. Assert: 이는 변경 불가능한 바인딩의 값을 변경하려는 시도임을 보장한다.
    2. Strue이면 TypeError 예외를 발생시킨다.
  6. unused를 반환한다.
참고

다음과 같은 ECMAScript 코드는 1 단계에서 바인딩이 존재하지 않게 되는 결과를 초래할 수 있습니다:

function f() { eval("var x; x = (delete x, 0);"); }

9.1.1.1.6 GetBindingValue ( N, S )

선언적 환경 레코드 envRec의 GetBindingValue 구체 메서드는 N (문자열)과 S (불리언)를 인자로 받아 ECMAScript 언어 값을 포함하는 정상 완료 또는 throw completion을 반환합니다. 이 메서드는 이름이 N인 바인딩된 식별자의 값을 반환합니다. 바인딩이 존재하지만 아직 초기화되지 않았다면 S 값과 무관하게 ReferenceError 예외가 발생합니다. 호출 시 다음 단계를 수행합니다:

  1. Assert: envRecN에 대한 바인딩을 가지고 있음을 보장한다.
  2. envRecN에 대한 바인딩이 초기화되지 않았다면 ReferenceError 예외를 발생시킨다.
  3. envRecN에 현재 바인딩된 값을 반환한다.

9.1.1.1.7 DeleteBinding ( N )

선언적 환경 레코드 envRec의 DeleteBinding 구체 메서드는 N (문자열)을 인자로 받아 불리언을 포함하는 정상 완료를 반환합니다. 이 메서드는 삭제 대상임이 명시적으로 지정된 바인딩만 삭제할 수 있습니다. 호출 시 다음 단계를 수행합니다:

  1. Assert: envRecN에 대한 바인딩을 가지고 있음을 보장한다.
  2. envRecN에 대한 바인딩을 삭제할 수 없다면 false를 반환한다.
  3. envRec에서 N에 대한 바인딩을 제거한다.
  4. true를 반환한다.

9.1.1.1.8 HasThisBinding ( )

선언적 환경 레코드 envRec의 HasThisBinding 구체 메서드는 인자가 없으며 false를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. false를 반환한다.
참고

일반적인 선언적 환경 레코드 (즉, 함수 환경 레코드모듈 환경 레코드가 아닌 것)는 this 바인딩을 제공하지 않습니다.

9.1.1.1.9 HasSuperBinding ( )

선언적 환경 레코드 envRec의 HasSuperBinding 구체 메서드는 인자가 없으며 false를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. false를 반환한다.
참고

일반적인 선언적 환경 레코드 (즉, 함수 환경 레코드모듈 환경 레코드가 아닌 것)는 super 바인딩을 제공하지 않습니다.

9.1.1.1.10 WithBaseObject ( )

선언적 환경 레코드 envRec의 WithBaseObject 구체 메서드는 인자가 없으며 undefined를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. undefined를 반환한다.

9.1.1.2 객체 환경 레코드

객체 환경 레코드는 자신의 바인딩 객체라 불리는 객체와 연관되어 있습니다. 객체 환경 레코드는 바인딩 객체의 프로퍼티 이름에 직접적으로 대응하는 문자열 식별자 이름 집합을 바인딩합니다. 프로퍼티 키IdentifierName 형태의 문자열이 아닌 것들은 바인딩된 식별자 집합에 포함되지 않습니다. 자신의 [[Enumerable]] 특성 설정과 상관없이 소유 및 상속된 프로퍼티 모두 집합에 포함됩니다. 객체에 프로퍼티가 동적으로 추가되거나 삭제될 수 있기 때문에, 객체 환경 레코드에 바인딩된 식별자 집합은 프로퍼티 추가/삭제 연산의 부수 효과로 잠재적으로 변경될 수 있습니다. 이런 부수 효과로 생성된 모든 바인딩은 해당 프로퍼티의 Writable 특성이 false이어도 변경 가능한 바인딩으로 간주합니다. 객체 환경 레코드에는 변경 불가능한(immutable) 바인딩이 존재하지 않습니다.

with 문(14.11)을 위해 생성된 객체 환경 레코드는 바인딩 객체를 함수 호출에서 암시적 this 값으로 제공할 수 있습니다. 이 기능은 불리언 타입의 [[IsWithEnvironment]] 필드로 제어됩니다.

객체 환경 레코드는 표 17에 나열된 추가 상태 필드를 가집니다.

표 17: 객체 환경 레코드의 추가 필드
필드 이름 의미
[[BindingObject]] 객체 환경 레코드의 바인딩 객체.
[[IsWithEnvironment]] 불리언 환경 레코드with 문을 위해 생성된 것인지를 나타냅니다.

9.1.1.2.1 HasBinding ( N )

객체 환경 레코드 envRec의 HasBinding 구체 메서드는 N (문자열)을 인자로 받아 불리언을 포함하는 정상 완료 또는 throw completion을 반환합니다. 이 메서드는 연관된 바인딩 객체에 N이라는 이름의 프로퍼티가 존재하는지 판단합니다. 호출 시 다음 단계를 수행합니다:

  1. bindingObjectenvRec.[[BindingObject]]로 둔다.
  2. foundBinding를 ? HasProperty(bindingObject, N)로 둔다.
  3. foundBindingfalse라면 false를 반환한다.
  4. envRec.[[IsWithEnvironment]]false라면 true를 반환한다.
  5. unscopables를 ? Get(bindingObject, %Symbol.unscopables%)로 둔다.
  6. unscopables객체라면,
    1. blockedToBoolean(? Get(unscopables, N))로 둔다.
    2. blockedtrue라면 false를 반환한다.
  7. true를 반환한다.

9.1.1.2.2 CreateMutableBinding ( N, D )

객체 환경 레코드 envRec의 CreateMutableBinding 구체 메서드는 N (문자열)과 D (불리언)를 인자로 받아 unused를 포함하는 정상 완료 또는 throw completion을 반환합니다. 이 메서드는 환경 레코드와 연관된 바인딩 객체에 N이라는 이름의 프로퍼티를 생성하고, 그 값을 undefined로 초기화합니다. Dtrue면 새 프로퍼티의 [[Configurable]] 특성을 true로, 아니면 false로 설정합니다. 호출 시 다음 단계를 수행합니다:

  1. bindingObjectenvRec.[[BindingObject]]로 둔다.
  2. DefinePropertyOrThrow(bindingObject, N, PropertyDescriptor { [[Value]]: undefined, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: D })를 수행한다.
  3. unused를 반환한다.
참고

보통 envRecN에 대한 바인딩을 갖지 않지만, 만약 갖고 있다면 DefinePropertyOrThrow의 의미론에 따라 기존 바인딩이 대체되거나 가려지거나, 비정상 완료가 반환될 수 있습니다.

9.1.1.2.3 CreateImmutableBinding ( N, S )

객체 환경 레코드의 CreateImmutableBinding 구체 메서드는 이 명세 안에서 사용되지 않습니다.

9.1.1.2.4 InitializeBinding ( N, V )

객체 환경 레코드 envRec의 InitializeBinding 구체 메서드는 N (문자열)과 V (ECMAScript 언어 값)를 인자로 받아 unused를 포함하는 정상 완료 또는 throw completion을 반환합니다. 이 메서드는 이름이 N인 식별자의 현재 바인딩 값을 V로 설정합니다. 호출 시 다음 단계를 수행합니다:

  1. envRec.SetMutableBinding(N, V, false)을 수행한다.
  2. unused를 반환한다.
참고

이 명세에서 객체 환경 레코드에 대한 CreateMutableBinding의 모든 사용은 곧바로 같은 이름에 대해 InitializeBinding을 호출합니다. 따라서 이 명세는 객체 환경 레코드의 바인딩 초기화 상태를 명시적으로 추적하지 않습니다.

9.1.1.2.5 SetMutableBinding ( N, V, S )

객체 환경 레코드 envRec의 SetMutableBinding 구체 메서드는 N (문자열), V (ECMAScript 언어 값), S (불리언)를 인자로 받아 unused를 포함하는 정상 완료 또는 throw completion을 반환합니다. 이 메서드는 환경 레코드와 연관된 바인딩 객체의 N이라는 이름의 프로퍼티 값을 V로 설정하려고 시도합니다. N이라는 이름의 프로퍼티가 보통 이미 존재하지만, 존재하지 않거나 쓰기 불가능한 경우 오류 처리는 S에 따라 결정됩니다. 호출 시 다음 단계를 수행합니다:

  1. bindingObjectenvRec.[[BindingObject]]로 둔다.
  2. stillExists를 ? HasProperty(bindingObject, N)로 둔다.
  3. stillExistsfalse이고 Strue라면 ReferenceError 예외를 발생시킨다.
  4. Set(bindingObject, N, V, S)를 수행한다.
  5. unused를 반환한다.

9.1.1.2.6 GetBindingValue ( N, S )

객체 환경 레코드 envRec의 GetBindingValue 구체 메서드는 N (문자열)과 S (불리언)를 인자로 받아 ECMAScript 언어 값을 포함하는 정상 완료 또는 throw completion을 반환합니다. 이 메서드는 연관된 바인딩 객체의 N 이름의 프로퍼티 값을 반환합니다. 프로퍼티는 이미 존재해야 하지만, 존재하지 않을 경우 결과는 S에 따라 달라집니다. 호출 시 다음 단계를 수행합니다:

  1. bindingObjectenvRec.[[BindingObject]]로 둔다.
  2. value를 ? HasProperty(bindingObject, N)로 둔다.
  3. valuefalse라면,
    1. Sfalse라면 undefined를 반환하고, 아니면 ReferenceError 예외를 발생시킨다.
  4. Get(bindingObject, N)를 반환한다.

9.1.1.2.7 DeleteBinding ( N )

객체 환경 레코드 envRec의 DeleteBinding 구체 메서드는 N (문자열)을 인자로 받아 불리언을 포함하는 정상 완료 또는 throw completion을 반환합니다. 이 메서드는 환경 객체의 [[Configurable]] 특성이 true인 프로퍼티에 대응되는 바인딩만 삭제할 수 있습니다. 호출 시 다음 단계를 수행합니다:

  1. bindingObjectenvRec.[[BindingObject]]로 둔다.
  2. bindingObject.[[Delete]](N)를 반환한다.

9.1.1.2.8 HasThisBinding ( )

객체 환경 레코드 envRec의 HasThisBinding 구체 메서드는 인자가 없으며 false를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. false를 반환한다.
참고

객체 환경 레코드this 바인딩을 제공하지 않습니다.

9.1.1.2.9 HasSuperBinding ( )

객체 환경 레코드 envRec의 HasSuperBinding 구체 메서드는 인자가 없으며 false를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. false를 반환한다.
참고

객체 환경 레코드super 바인딩을 제공하지 않습니다.

9.1.1.2.10 WithBaseObject ( )

객체 환경 레코드 envRec의 WithBaseObject 구체 메서드는 인자가 없으며 객체 또는 undefined를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. envRec.[[IsWithEnvironment]]true라면, envRec.[[BindingObject]]를 반환한다.
  2. 그렇지 않으면 undefined를 반환한다.

9.1.1.3 함수 환경 레코드

함수 환경 레코드선언적 환경 레코드이며, 함수의 최상위 스코프를 표현하는 데 사용되고, 함수가 ArrowFunction이 아닐 경우 this 바인딩을 제공합니다. 함수가 ArrowFunction이 아니고 super를 참조한다면, 해당 함수 환경 레코드는 함수 내부에서 super 메서드 호출을 수행하는 데 사용되는 상태도 포함합니다.

함수 환경 레코드는 표 18에 나열된 추가 상태 필드를 가집니다.

표 18: 함수 환경 레코드의 추가 필드
필드 이름 의미
[[ThisValue]] ECMAScript 언어 값 이 함수 호출에 사용되는 this 값입니다.
[[ThisBindingStatus]] lexical, initialized, 또는 uninitialized 값이 lexical라면, 이는 ArrowFunction이며 로컬 this 값을 가지지 않습니다.
[[FunctionObject]] ECMAScript 함수 객체 환경 레코드가 생성된 호출을 야기한 함수 객체입니다.
[[NewTarget]] 생성자 또는 undefined 환경 레코드[[Construct]] 내부 메서드에 의해 생성되었다면, [[NewTarget]][[Construct]]newTarget 파라미터 값입니다. 그렇지 않으면 값은 undefined입니다.

함수 환경 레코드는 선언적 환경 레코드의 모든 메서드(표 16 참조)를 지원하며, HasThisBinding과 HasSuperBinding을 제외한 모든 메서드는 동일한 명세를 따릅니다. 또한, 함수 환경 레코드는 표 19에 나열된 메서드들도 지원합니다:

표 19: 함수 환경 레코드의 추가 메서드
메서드 목적
GetThisBinding() 환경 레코드this 바인딩 값을 반환합니다. this 바인딩이 초기화되지 않았다면 ReferenceError를 발생시킵니다.

9.1.1.3.1 BindThisValue ( envRec, V )

추상 연산 BindThisValue는 envRec (함수 환경 레코드)와 V (ECMAScript 언어 값)를 인자로 받아, unused를 포함하는 정상 완료 또는 throw completion을 반환합니다. 이 연산은 envRec.[[ThisValue]]를 세팅하고, 초기화되었음을 기록합니다. 호출 시 다음 단계를 수행합니다:

  1. Assert: envRec.[[ThisBindingStatus]]lexical이 아님을 보장한다.
  2. envRec.[[ThisBindingStatus]]initialized라면, ReferenceError 예외를 발생시킨다.
  3. envRec.[[ThisValue]]V로 설정한다.
  4. envRec.[[ThisBindingStatus]]initialized로 설정한다.
  5. unused를 반환한다.

9.1.1.3.2 HasThisBinding ( )

함수 환경 레코드 envRec의 HasThisBinding 구체 메서드는 인자가 없으며 불리언을 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. envRec.[[ThisBindingStatus]]lexical이면 false를, 아니면 true를 반환한다.

9.1.1.3.3 HasSuperBinding ( )

함수 환경 레코드 envRec의 HasSuperBinding 구체 메서드는 인자가 없으며 불리언을 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. envRec.[[ThisBindingStatus]]lexical라면 false를 반환한다.
  2. envRec.[[FunctionObject]].[[HomeObject]]undefined라면 false를, 아니면 true를 반환한다.

9.1.1.3.4 GetThisBinding ( )

함수 환경 레코드 envRec의 GetThisBinding 구체 메서드는 인자가 없으며 ECMAScript 언어 값을 포함하는 정상 완료 또는 throw completion을 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. Assert: envRec.[[ThisBindingStatus]]lexical이 아님을 보장한다.
  2. envRec.[[ThisBindingStatus]]uninitialized라면 ReferenceError 예외를 발생시킨다.
  3. envRec.[[ThisValue]]를 반환한다.

9.1.1.3.5 GetSuperBase ( envRec )

추상 연산 GetSuperBase는 envRec (함수 환경 레코드)를 인자로 받아 객체, null, 또는 undefined를 반환합니다. 이 연산은 envRec에 바인딩된 super 프로퍼티 접근의 기반이 되는 객체를 반환합니다. 값이 undefined이면, 그러한 접근이 런타임 오류를 발생시킴을 나타냅니다. 호출 시 다음 단계를 수행합니다:

  1. homeenvRec.[[FunctionObject]].[[HomeObject]]로 둔다.
  2. homeundefined라면 undefined를 반환한다.
  3. Assert: homeordinary object임을 보장한다.
  4. home.[[GetPrototypeOf]]()의 결과를 반환한다.

9.1.1.4 전역 환경 레코드

전역 환경 레코드는 공통 realm에서 처리되는 모든 ECMAScript Script 요소가 공유하는 가장 바깥쪽 스코프를 나타내는 데 사용됩니다. 전역 환경 레코드는 내장 글로벌(19), 글로벌 객체의 프로퍼티, 그리고 Script 내에서 발생하는 모든 최상위 선언(8.2.9, 8.2.11)에 대한 바인딩을 제공합니다.

전역 환경 레코드는 논리적으로 단일 레코드이지만, 객체 환경 레코드선언적 환경 레코드를 캡슐화하는 복합체로 명세되어 있습니다. 객체 환경 레코드의 기반 객체는 관련 Realm Record글로벌 객체입니다. 이 글로벌 객체는 전역 환경 레코드의 GetThisBinding 구체 메서드가 반환하는 값입니다. 전역 환경 레코드의 객체 환경 레코드 구성요소에는 모든 내장 글로벌(19)과 글로벌 코드에 포함된 FunctionDeclaration, GeneratorDeclaration, AsyncFunctionDeclaration, AsyncGeneratorDeclaration, 또는 VariableStatement로 도입된 바인딩이 포함됩니다. 글로벌 코드의 그 밖의 모든 ECMAScript 선언에 대한 바인딩은 전역 환경 레코드의 선언적 환경 레코드 구성 요소에 포함됩니다.

프로퍼티는 글로벌 객체에 직접 생성될 수 있습니다. 따라서 전역 환경 레코드의 객체 환경 레코드 구성 요소에는 FunctionDeclaration, GeneratorDeclaration, AsyncFunctionDeclaration, AsyncGeneratorDeclaration, VariableDeclaration 선언에 의해 명시적으로 생성된 바인딩과 글로벌 객체의 프로퍼티로 암묵적으로 생성된 바인딩이 모두 포함될 수 있습니다. 어떤 바인딩이 선언을 통해 명시적으로 생성되었는지 식별하기 위해, 전역 환경 레코드는 CreateGlobalVarBindingCreateGlobalFunctionBinding 추상 연산에 사용된 이름 목록을 유지합니다.

전역 환경 레코드는 표 20의 추가 필드와 표 21의 추가 메서드를 가집니다.

표 20: 전역 환경 레코드의 추가 필드
필드 이름 의미
[[ObjectRecord]] 객체 환경 레코드 바인딩 객체는 글로벌 객체입니다. 여기에는 관련 realm의 글로벌 코드에서 내장 바인딩, FunctionDeclaration, GeneratorDeclaration, AsyncFunctionDeclaration, AsyncGeneratorDeclaration, VariableDeclaration의 바인딩이 포함됩니다.
[[GlobalThisValue]] 객체 글로벌 스코프에서 this가 반환하는 값입니다. 호스트는 어떤 ECMAScript 객체 값이라도 제공할 수 있습니다.
[[DeclarativeRecord]] 선언적 환경 레코드 관련 realm 코드의 글로벌 코드 내에서 FunctionDeclaration, GeneratorDeclaration, AsyncFunctionDeclaration, AsyncGeneratorDeclaration, VariableDeclaration 바인딩을 제외한 모든 선언의 바인딩을 포함합니다.
표 21: 전역 환경 레코드의 추가 메서드
메서드 목적
GetThisBinding() 환경 레코드this 바인딩 값을 반환합니다.

9.1.1.4.1 HasBinding ( N )

전역 환경 레코드 envRec의 HasBinding 구체 메서드는 N (문자열)을 인자로 받아 불리언을 포함하는 정상 완료 또는 throw completion을 반환합니다. 이 메서드는 인자 식별자가 레코드에 바인딩된 식별자 중 하나인지 판단합니다. 호출 시 다음 단계를 수행합니다:

  1. DclRecenvRec.[[DeclarativeRecord]]로 둔다.
  2. DclRec.HasBinding(N)이 true라면 true를 반환한다.
  3. ObjRecenvRec.[[ObjectRecord]]로 둔다.
  4. ObjRec.HasBinding(N)을 반환한다.

9.1.1.4.2 CreateMutableBinding ( N, D )

전역 환경 레코드 envRec의 CreateMutableBinding 구체 메서드는 N (문자열)과 D (불리언)를 인자로 받아 unused를 포함하는 정상 완료 또는 throw completion을 반환합니다. 이름 N에 대해 초기화되지 않은 새로운 변경 가능한 바인딩을 생성합니다. 바인딩은 관련 DeclarativeRecord에 생성됩니다. DeclarativeRecord에 N에 대한 바인딩이 이미 존재해서는 안 됩니다. Dtrue이면, 새로 생성된 바인딩은 삭제 대상임이 표시됩니다. 호출 시 다음 단계를 수행합니다:

  1. DclRecenvRec.[[DeclarativeRecord]]로 둔다.
  2. DclRec.HasBinding(N)이 true라면 TypeError 예외를 발생시킨다.
  3. DclRec.CreateMutableBinding(N, D)을 반환한다.

9.1.1.4.3 CreateImmutableBinding ( N, S )

전역 환경 레코드 envRec의 CreateImmutableBinding 구체 메서드는 N (문자열)과 S (불리언)를 인자로 받아 unused를 포함하는 정상 완료 또는 throw completion을 반환합니다. 이름 N에 대해 초기화되지 않은 새로운 변경 불가능한 바인딩을 생성합니다. 이 환경 레코드 내에 N에 대한 바인딩이 이미 존재해서는 안 됩니다. Strue이면, 새로 생성된 바인딩이 strict 바인딩임을 표시합니다. 호출 시 다음 단계를 수행합니다:

  1. DclRecenvRec.[[DeclarativeRecord]]로 둔다.
  2. DclRec.HasBinding(N)이 true라면 TypeError 예외를 발생시킨다.
  3. DclRec.CreateImmutableBinding(N, S)을 반환한다.

9.1.1.4.4 InitializeBinding ( N, V )

전역 환경 레코드 envRec의 InitializeBinding 구체 메서드는 N (문자열)과 V (ECMAScript 언어 값)를 인자로 받아 unused를 포함하는 정상 완료 또는 throw completion을 반환합니다. 이 메서드는 이름이 N인 식별자의 현재 바인딩 값을 V로 설정합니다. N에 대한 초기화되지 않은 바인딩이 이미 존재해야 합니다. 호출 시 다음 단계를 수행합니다:

  1. DclRecenvRec.[[DeclarativeRecord]]로 둔다.
  2. DclRec.HasBinding(N)이 true라면,
    1. DclRec.InitializeBinding(N, V)을 반환한다.
  3. Assert: 바인딩이 존재한다면, 반드시 객체 환경 레코드에 존재해야 한다.
  4. ObjRecenvRec.[[ObjectRecord]]로 둔다.
  5. ObjRec.InitializeBinding(N, V)을 반환한다.

9.1.1.4.5 SetMutableBinding ( N, V, S )

전역 환경 레코드 envRec의 SetMutableBinding 구체 메서드는 N (문자열), V (ECMAScript 언어 값), S (불리언)를 인자로 받아 unused를 포함하는 정상 완료 또는 throw completion을 반환합니다. 이 메서드는 이름이 N인 식별자의 현재 바인딩 값을 V로 변경하려고 시도합니다. 바인딩이 변경 불가능한 경우 Strue이면 TypeError를 발생시킵니다. N이라는 이름의 프로퍼티가 보통 이미 존재하지만, 존재하지 않거나 쓰기 불가능한 경우 오류 처리는 S에 따라 결정됩니다. 호출 시 다음 단계를 수행합니다:

  1. DclRecenvRec.[[DeclarativeRecord]]로 둔다.
  2. DclRec.HasBinding(N)이 true라면,
    1. DclRec.SetMutableBinding(N, V, S)을 반환한다.
  3. ObjRecenvRec.[[ObjectRecord]]로 둔다.
  4. ObjRec.SetMutableBinding(N, V, S)을 반환한다.

9.1.1.4.6 GetBindingValue ( N, S )

전역 환경 레코드 envRec의 GetBindingValue 구체 메서드는 N (문자열)과 S (불리언)를 인자로 받아 ECMAScript 언어 값을 포함하는 정상 완료 또는 throw completion을 반환합니다. 이 메서드는 이름이 N인 바인딩된 식별자의 값을 반환합니다. 바인딩이 초기화되지 않은 바인딩이면 ReferenceError 예외를 발생시킵니다. N이라는 이름의 프로퍼티가 보통 이미 존재하지만, 존재하지 않거나 쓰기 불가능한 경우 결과는 S에 따라 결정됩니다. 호출 시 다음 단계를 수행합니다:

  1. DclRecenvRec.[[DeclarativeRecord]]로 둔다.
  2. DclRec.HasBinding(N)이 true라면,
    1. DclRec.GetBindingValue(N, S)을 반환한다.
  3. ObjRecenvRec.[[ObjectRecord]]로 둔다.
  4. ObjRec.GetBindingValue(N, S)을 반환한다.

9.1.1.4.7 DeleteBinding ( N )

전역 환경 레코드 envRec의 DeleteBinding 구체 메서드는 N (문자열)을 인자로 받아 불리언을 포함하는 정상 완료 또는 throw completion을 반환합니다. 이 메서드는 삭제 대상임이 명시적으로 지정된 바인딩만 삭제할 수 있습니다. 호출 시 다음 단계를 수행합니다:

  1. DclRecenvRec.[[DeclarativeRecord]]로 둔다.
  2. DclRec.HasBinding(N)이 true라면,
    1. DclRec.DeleteBinding(N)을 반환한다.
  3. ObjRecenvRec.[[ObjectRecord]]로 둔다.
  4. globalObjectObjRec.[[BindingObject]]로 둔다.
  5. existingProp를 ? HasOwnProperty(globalObject, N)로 둔다.
  6. existingProptrue라면,
    1. ObjRec.DeleteBinding(N)을 반환한다.
  7. true를 반환한다.

9.1.1.4.8 HasThisBinding ( )

전역 환경 레코드 envRec의 HasThisBinding 구체 메서드는 인자가 없으며 true를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. true를 반환한다.
참고

전역 환경 레코드는 항상 this 바인딩을 제공합니다.

9.1.1.4.9 HasSuperBinding ( )

전역 환경 레코드 envRec의 HasSuperBinding 구체 메서드는 인자가 없으며 false를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. false를 반환한다.
참고

전역 환경 레코드super 바인딩을 제공하지 않습니다.

9.1.1.4.10 WithBaseObject ( )

전역 환경 레코드 envRec의 WithBaseObject 구체 메서드는 인자가 없으며 undefined를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. undefined를 반환한다.

9.1.1.4.11 GetThisBinding ( )

전역 환경 레코드 envRec의 GetThisBinding 구체 메서드는 인자가 없으며 객체를 포함하는 정상 완료를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. envRec.[[GlobalThisValue]]를 반환한다.

9.1.1.4.12 HasLexicalDeclaration ( envRec, N )

추상 연산 HasLexicalDeclaration은 envRec (전역 환경 레코드)와 N (문자열)을 인자로 받아 불리언을 반환합니다. 이 연산은 인자 식별자가 LexicalDeclaration 또는 ClassDeclaration과 같은 렉시컬 선언을 사용해 envRec에 바인딩되어 있는지 판단합니다. 호출 시 다음 단계를 수행합니다:

  1. DclRecenvRec.[[DeclarativeRecord]]로 둔다.
  2. DclRec.HasBinding(N)을 반환한다.

9.1.1.4.13 HasRestrictedGlobalProperty ( envRec, N )

추상 연산 HasRestrictedGlobalProperty는 envRec (전역 환경 레코드)와 N (문자열)을 인자로 받아 불리언을 포함하는 정상 완료 또는 throw completion을 반환합니다. 이 연산은 인자 식별자가 글로벌 객체의 글로벌 렉시컬 바인딩에 의해 가려져서는 안 되는 프로퍼티 이름인지 판단합니다. 호출 시 다음 단계를 수행합니다:

  1. ObjRecenvRec.[[ObjectRecord]]로 둔다.
  2. globalObjectObjRec.[[BindingObject]]로 둔다.
  3. existingProp를 ? globalObject.[[GetOwnProperty]](N)로 둔다.
  4. existingPropundefined라면 false를 반환한다.
  5. existingProp.[[Configurable]]true라면 false를 반환한다.
  6. true를 반환한다.
참고

글로벌 객체에 var나 function 선언을 사용하지 않고 직접 생성된 프로퍼티가 존재할 수 있습니다. 글로벌 렉시컬 바인딩은 글로벌 객체의 non-configurable 프로퍼티와 같은 이름으로는 생성될 수 없습니다. "undefined" 글로벌 프로퍼티가 그 예입니다.

9.1.1.4.14 CanDeclareGlobalVar ( envRec, N )

추상 연산 CanDeclareGlobalVar는 envRec (전역 환경 레코드)와 N (문자열)을 인자로 받아, 불리언을 포함하는 정상 완료 또는 throw completion을 반환합니다. 이 연산은 동일한 N 인자로 CreateGlobalVarBinding을 호출할 경우 성공할지 판단합니다. 중복 var 선언 및 기존 글로벌 객체 프로퍼티에 대한 var 선언은 허용됩니다. 호출 시 다음 단계를 수행합니다:

  1. ObjRecenvRec.[[ObjectRecord]]로 둔다.
  2. globalObjectObjRec.[[BindingObject]]로 둔다.
  3. hasProperty를 ? HasOwnProperty(globalObject, N)로 둔다.
  4. hasPropertytrue라면 true를 반환한다.
  5. IsExtensible(globalObject)를 반환한다.

9.1.1.4.15 CanDeclareGlobalFunction ( envRec, N )

추상 연산 CanDeclareGlobalFunction은 envRec (전역 환경 레코드)와 N (문자열)을 인자로 받아, 불리언을 포함하는 정상 완료 또는 throw completion을 반환합니다. 이 연산은 동일한 N 인자로 CreateGlobalFunctionBinding을 호출할 경우 성공할지 판단합니다. 호출 시 다음 단계를 수행합니다:

  1. ObjRecenvRec.[[ObjectRecord]]로 둔다.
  2. globalObjectObjRec.[[BindingObject]]로 둔다.
  3. existingProp를 ? globalObject.[[GetOwnProperty]](N)로 둔다.
  4. existingPropundefined라면, ? IsExtensible(globalObject)를 반환한다.
  5. existingProp.[[Configurable]]true라면 true를 반환한다.
  6. IsDataDescriptor(existingProp)가 true이고 existingProp의 특성 값이 { [[Writable]]: true, [[Enumerable]]: true }라면 true를 반환한다.
  7. false를 반환한다.

9.1.1.4.16 CreateGlobalVarBinding ( envRec, N, D )

추상 연산 CreateGlobalVarBinding은 envRec (전역 환경 레코드), N (문자열), D (불리언)를 인자로 받아, unused를 포함하는 정상 완료 또는 throw completion을 반환합니다. 연관된 객체 환경 레코드에 변경 가능한 바인딩을 생성 및 초기화합니다. 바인딩이 이미 존재한다면 재사용하며, 이미 초기화된 것으로 간주합니다. 호출 시 다음 단계를 수행합니다:

  1. ObjRecenvRec.[[ObjectRecord]]로 둔다.
  2. globalObjectObjRec.[[BindingObject]]로 둔다.
  3. hasProperty를 ? HasOwnProperty(globalObject, N)로 둔다.
  4. extensible을 ? IsExtensible(globalObject)로 둔다.
  5. hasPropertyfalse이고 extensibletrue라면,
    1. ObjRec.CreateMutableBinding(N, D)을 수행한다.
    2. ObjRec.InitializeBinding(N, undefined)을 수행한다.
  6. unused를 반환한다.

9.1.1.4.17 CreateGlobalFunctionBinding ( envRec, N, V, D )

추상 연산 CreateGlobalFunctionBinding은 envRec (전역 환경 레코드), N (문자열), V (ECMAScript 언어 값), D (불리언)를 인자로 받아, unused를 포함하는 정상 완료 또는 throw completion을 반환합니다. 연관된 객체 환경 레코드에 변경 가능한 바인딩을 생성 및 초기화합니다. 바인딩이 이미 존재한다면 대체합니다. 호출 시 다음 단계를 수행합니다:

  1. ObjRecenvRec.[[ObjectRecord]]로 둔다.
  2. globalObjectObjRec.[[BindingObject]]로 둔다.
  3. existingProp를 ? globalObject.[[GetOwnProperty]](N)로 둔다.
  4. existingPropundefined이거나 existingProp.[[Configurable]]true라면,
    1. desc를 PropertyDescriptor { [[Value]]: V, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: D }로 둔다.
  5. 그 외의 경우,
    1. desc를 PropertyDescriptor { [[Value]]: V }로 둔다.
  6. DefinePropertyOrThrow(globalObject, N, desc)을 수행한다.
  7. Set(globalObject, N, V, false)을 수행한다.
  8. unused를 반환한다.
참고

전역 함수 선언은 항상 글로벌 객체의 own 프로퍼티로 표현됩니다. 가능할 경우, 기존 own 프로퍼티를 표준 특성 값 집합을 가지도록 재설정합니다. 7 단계는 InitializeBinding 구체 메서드를 호출하는 것과 동등하며, globalObject가 Proxy인 경우 동일한 Proxy trap 호출 시퀀스를 생성합니다.

9.1.1.5 모듈 환경 레코드

모듈 환경 레코드선언적 환경 레코드로, ECMAScript Module의 외부 스코프를 표현하는 데 사용됩니다. 일반적인 변경 가능/불변 바인딩 외에, 모듈 환경 레코드는 다른 환경 레코드에 존재하는 대상 바인딩에 간접적으로 접근할 수 있는 변경 불가능한 import 바인딩도 제공합니다.

모듈 환경 레코드는 선언적 환경 레코드의 모든 메서드(표 16 참조)를 지원하며, GetBindingValue, DeleteBinding, HasThisBinding, GetThisBinding을 제외한 모든 메서드는 동일한 명세를 따릅니다. 또한, 모듈 환경 레코드는 표 22에 나열된 메서드들도 지원합니다:

표 22: 모듈 환경 레코드의 추가 메서드
메서드 목적
GetThisBinding() 환경 레코드this 바인딩의 값을 반환합니다.

9.1.1.5.1 GetBindingValue ( N, S )

모듈 환경 레코드 envRec의 GetBindingValue 구체 메서드는 N (문자열), S (불리언)를 인자로 받아 ECMAScript 언어 값을 포함하는 정상 완료 또는 throw completion을 반환합니다. 이 메서드는 이름이 N인 바인딩된 식별자의 값을 반환합니다. 단, 바인딩이 간접 바인딩인 경우 대상 바인딩의 값을 반환합니다. 바인딩이 존재하지만 아직 초기화되지 않았다면 ReferenceError가 발생합니다. 호출 시 다음 단계를 수행합니다:

  1. Assert: Strue임을 보장한다.
  2. Assert: envRecN에 대한 바인딩이 존재함을 보장한다.
  3. N에 대한 바인딩이 간접 바인딩이라면,
    1. 이 바인딩이 생성될 때 제공된 indirection 값 MN2를 얻는다.
    2. targetEnvM.[[Environment]]로 둔다.
    3. targetEnvempty라면 ReferenceError 예외를 발생시킨다.
    4. targetEnv.GetBindingValue(N2, true)를 반환한다.
  4. envRecN에 대한 바인딩이 초기화되지 않았다면 ReferenceError 예외를 발생시킨다.
  5. envRecN에 현재 바인딩된 값을 반환한다.
참고

S는 항상 true입니다. 왜냐하면 Module은 항상 엄격 모드 코드이기 때문입니다.

9.1.1.5.2 DeleteBinding ( N )

모듈 환경 레코드의 DeleteBinding 구체 메서드는 이 명세 안에서 사용되지 않습니다.

참고

모듈 환경 레코드는 엄격 코드 내에서만 사용되며, 조기 오류 규칙에 의해 엄격 코드 내에서 Reference Record모듈 환경 레코드 바인딩으로 해석되는 경우 delete 연산자를 사용할 수 없습니다. 13.5.1.1 참고.

9.1.1.5.3 HasThisBinding ( )

모듈 환경 레코드 envRec의 HasThisBinding 구체 메서드는 인자가 없으며 true를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. true를 반환한다.
참고

모듈 환경 레코드는 항상 this 바인딩을 제공합니다.

9.1.1.5.4 GetThisBinding ( )

모듈 환경 레코드 envRec의 GetThisBinding 구체 메서드는 인자가 없으며 undefined를 포함하는 정상 완료를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. undefined를 반환한다.

9.1.1.5.5 CreateImportBinding ( envRec, N, M, N2 )

추상 연산 CreateImportBinding은 envRec (모듈 환경 레코드), N (문자열), M (모듈 레코드), N2 (문자열)을 인자로 받아 unused를 반환합니다. N에 대해 초기화된 변경 불가능한 간접 바인딩을 새롭게 생성합니다. envRec 내에 이미 N에 대한 바인딩이 존재해서는 안 됩니다. N2M모듈 환경 레코드에 존재하는 바인딩의 이름입니다. 새 바인딩에 대한 값 접근은 간접적으로 대상 바인딩의 값을 접근합니다. 호출 시 다음 단계를 수행합니다:

  1. Assert: envRecN에 대한 바인딩이 이미 존재하지 않음을 보장한다.
  2. Assert: M.[[Environment]]가 인스턴스화될 때 N2에 대한 직접 바인딩을 가지게 됨을 보장한다.
  3. envRecN에 대해 MN2를 대상 바인딩으로 참조하는 변경 불가능한 간접 바인딩을 생성하고, 이 바인딩이 초기화되었음을 기록한다.
  4. unused를 반환한다.

9.1.2 환경 레코드 연산

다음의 추상 연산들은 이 명세에서 환경 레코드에 대해 동작할 때 사용됩니다:

9.1.2.1 GetIdentifierReference ( env, name, strict )

추상 연산 GetIdentifierReference는 env (환경 레코드 또는 null), name (문자열), strict (불리언)을 인자로 받아, Reference Record를 포함하는 정상 완료 또는 throw completion을 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. envnull이면,
    1. Reference Record { [[Base]]: unresolvable, [[ReferencedName]]: name, [[Strict]]: strict, [[ThisValue]]: empty }를 반환한다.
  2. exists를 ? env.HasBinding(name)로 둔다.
  3. existstrue이면,
    1. Reference Record { [[Base]]: env, [[ReferencedName]]: name, [[Strict]]: strict, [[ThisValue]]: empty }를 반환한다.
  4. 그 외의 경우,
    1. outerenv.[[OuterEnv]]로 둔다.
    2. GetIdentifierReference(outer, name, strict)를 반환한다.

9.1.2.2 NewDeclarativeEnvironment ( E )

추상 연산 NewDeclarativeEnvironment는 E (환경 레코드 또는 null)를 인자로 받아 선언적 환경 레코드를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. env를 새로운 선언적 환경 레코드 (바인딩 없음)로 둔다.
  2. env.[[OuterEnv]]E로 설정한다.
  3. env를 반환한다.

9.1.2.3 NewObjectEnvironment ( O, W, E )

추상 연산 NewObjectEnvironment는 O (객체), W (불리언), E (환경 레코드 또는 null)를 인자로 받아 객체 환경 레코드를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. env를 새로운 객체 환경 레코드로 둔다.
  2. env.[[BindingObject]]O로 설정한다.
  3. env.[[IsWithEnvironment]]W로 설정한다.
  4. env.[[OuterEnv]]E로 설정한다.
  5. env를 반환한다.

9.1.2.4 NewFunctionEnvironment ( F, newTarget )

추상 연산 NewFunctionEnvironment는 F (ECMAScript 함수 객체), newTarget (객체 또는 undefined)를 인자로 받아 함수 환경 레코드를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. env를 새로운 함수 환경 레코드 (바인딩 없음)로 둔다.
  2. env.[[FunctionObject]]F로 설정한다.
  3. F.[[ThisMode]]lexical이면, env.[[ThisBindingStatus]]lexical로 설정한다.
  4. 그 외의 경우, env.[[ThisBindingStatus]]uninitialized로 설정한다.
  5. env.[[NewTarget]]newTarget로 설정한다.
  6. env.[[OuterEnv]]F.[[Environment]]로 설정한다.
  7. env를 반환한다.

9.1.2.5 NewGlobalEnvironment ( G, thisValue )

추상 연산 NewGlobalEnvironment는 G (객체), thisValue (객체)를 인자로 받아 전역 환경 레코드를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. objRecNewObjectEnvironment(G, false, null)로 둔다.
  2. dclRecNewDeclarativeEnvironment(null)로 둔다.
  3. env를 새로운 전역 환경 레코드로 둔다.
  4. env.[[ObjectRecord]]objRec로 설정한다.
  5. env.[[GlobalThisValue]]thisValue로 설정한다.
  6. env.[[DeclarativeRecord]]dclRec로 설정한다.
  7. env.[[OuterEnv]]null로 설정한다.
  8. env를 반환한다.

9.1.2.6 NewModuleEnvironment ( E )

추상 연산 NewModuleEnvironment는 E (환경 레코드)를 인자로 받아 모듈 환경 레코드를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. env를 새로운 모듈 환경 레코드 (바인딩 없음)로 둔다.
  2. env.[[OuterEnv]]E로 설정한다.
  3. env를 반환한다.

9.2 PrivateEnvironment 레코드

PrivateEnvironment 레코드는 ECMAScript 코드 내의 ClassDeclarationClassExpression의 렉시컬 중첩 구조를 기반으로 Private Name을 추적하기 위해 사용되는 명세 메커니즘입니다. 이들은 환경 레코드와 유사하지만 구분됩니다. 각 PrivateEnvironment 레코드는 하나의 ClassDeclaration 또는 ClassExpression에 연관됩니다. 해당 클래스가 평가될 때마다, 그 클래스에서 선언된 Private Name을 기록하기 위해 새로운 PrivateEnvironment 레코드가 생성됩니다.

PrivateEnvironment 레코드표 23에 정의된 필드를 가집니다.

표 23: PrivateEnvironment 레코드 필드
필드명 값 타입 의미
[[OuterPrivateEnvironment]] PrivateEnvironment 레코드 또는 null 가장 가까운 포함 클래스의 PrivateEnvironment 레코드. 이 PrivateEnvironment 레코드가 연관된 클래스가 다른 클래스에 포함되어 있지 않으면 null.
[[Names]] List of Private Name 이 클래스가 선언한 Private Name 목록.

9.2.1 PrivateEnvironment 레코드 연산

다음의 추상 연산들은 이 명세에서 PrivateEnvironment 레코드에 대해 동작할 때 사용됩니다:

9.2.1.1 NewPrivateEnvironment ( outerPrivateEnv )

추상 연산 NewPrivateEnvironment는 outerPrivateEnv (PrivateEnvironment 레코드 또는 null)를 인자로 받아 PrivateEnvironment 레코드를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. names를 새로운 빈 List로 둔다.
  2. PrivateEnvironment 레코드 { [[OuterPrivateEnvironment]]: outerPrivateEnv, [[Names]]: names }를 반환한다.

9.2.1.2 ResolvePrivateIdentifier ( privateEnv, identifier )

추상 연산 ResolvePrivateIdentifier는 privateEnv (PrivateEnvironment 레코드), identifier (문자열)를 인자로 받아 Private Name를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. namesprivateEnv.[[Names]]로 둔다.
  2. names의 각 Private Name pn에 대해,
    1. pn.[[Description]]identifier라면,
      1. pn를 반환한다.
  3. outerPrivateEnvprivateEnv.[[OuterPrivateEnvironment]]로 둔다.
  4. Assert: outerPrivateEnvnull이 아님을 보장한다.
  5. ResolvePrivateIdentifier(outerPrivateEnv, identifier)를 반환한다.

9.3 Realm

평가되기 전에, 모든 ECMAScript 코드는 realm에 연관되어야 합니다. 개념적으로, realm은 일련의 내장 객체 집합, ECMAScript 글로벌 환경, 그 글로벌 환경의 범위 내에서 로드된 모든 ECMAScript 코드, 기타 관련 상태와 리소스로 구성됩니다.

realm은 이 명세에서 Realm Record로 표현되며, 표 24에 명시된 필드를 가집니다:

표 24: Realm Record 필드
필드명 의미
[[AgentSignifier]] agent signifier realm을 소유하는 agent
[[Intrinsics]] Record (필드명은 intrinsic 키, 값은 객체) realm에 연관된 코드가 사용하는 intrinsic 값들
[[GlobalObject]] 객체 realm글로벌 객체
[[GlobalEnv]] 전역 환경 레코드 realm의 글로벌 환경
[[TemplateMap]] List of Records (필드: [[Site]] (TemplateLiteral Parse Node), [[Array]] (배열))

템플릿 객체는 각 realm마다 Realm Record[[TemplateMap]]을 사용해 별도로 정규화됩니다. 각 [[Site]] 값은 Parse Node이며, TemplateLiteral입니다. 연관된 [[Array]] 값은 태그 함수에 전달되는 해당 템플릿 객체입니다.

참고 1
어떤 Parse Node가 도달 불가능해지면, 그에 대응하는 [[Array]]도 도달 불가능해지며, 구현체가 그 쌍을 [[TemplateMap]] 리스트에서 제거하더라도 관찰 불가합니다.
[[LoadedModules]] List of LoadedModuleRequest Record

realm이 import한 specifier 문자열에서 해석된 Module Record로의 맵입니다. 리스트에는 Record r1, r2가 ModuleRequestsEqual(r1, r2)가 true인 경우 같이 존재할 수 없습니다.

참고 2
HostLoadImportedModule (16.2.1.10 참고 1)에서 언급했듯, Realm Record[[LoadedModules]]import() 표현식이 active script나 module이 없는 컨텍스트에서 실행될 때만 사용됩니다.
[[HostDefined]] 아무 값 (기본값은 undefined) 호스트Realm Record에 추가 정보를 연결할 필요가 있을 때 사용하는 필드입니다.

9.3.1 InitializeHostDefinedRealm ( )

추상 연산 InitializeHostDefinedRealm는 인자가 없으며, unused를 포함하는 정상 완료 또는 throw completion을 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. realm을 새로운 Realm Record로 둔다.
  2. CreateIntrinsics(realm)을 수행한다.
  3. realm.[[AgentSignifier]]AgentSignifier()로 설정한다.
  4. realm.[[TemplateMap]]을 새로운 빈 List로 설정한다.
  5. newContext를 새로운 실행 컨텍스트로 둔다.
  6. newContext의 Function을 null로 설정한다.
  7. newContextRealmrealm으로 설정한다.
  8. newContext의 ScriptOrModule을 null로 설정한다.
  9. newContext실행 컨텍스트 스택에 푸시한다; newContext실행 중인 실행 컨텍스트가 된다.
  10. 호스트realm글로벌 객체익조틱 객체를 사용해야 한다면,
    1. global을 그런 객체로, 호스트 정의 방식으로 생성한다.
  11. 그 외의 경우,
    1. globalOrdinaryObjectCreate(realm.[[Intrinsics]].[[%Object.prototype%]])로 둔다.
  12. 호스트realm의 글로벌 스코프의 this 바인딩이 글로벌 객체 이외의 객체를 반환해야 한다면,
    1. thisValue를 그런 객체로, 호스트 정의 방식으로 생성한다.
  13. 그 외의 경우,
    1. thisValueglobal로 둔다.
  14. realm.[[GlobalObject]]global로 설정한다.
  15. realm.[[GlobalEnv]]NewGlobalEnvironment(global, thisValue)로 설정한다.
  16. SetDefaultGlobalBindings(realm)을 수행한다.
  17. 호스트 정의 글로벌 객체 프로퍼티들을 global에 생성한다.
  18. unused를 반환한다.

9.3.2 CreateIntrinsics ( realmRec )

추상 연산 CreateIntrinsics는 realmRec (Realm Record)를 인자로 받아 unused를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. realmRec.[[Intrinsics]]를 새로운 Record로 설정한다.
  2. realmRec.[[Intrinsics]]의 각 필드를 표 6에 명시된 값들로 설정한다. 필드명은 표의 첫 번째 열에 기재된 이름이다. 각 필드의 값은, 이 명세의 각 객체 명세에 따라 완전히, 재귀적으로 프로퍼티 값이 채워진 새로운 객체 값이다. 모든 객체 프로퍼티 값은 새로 생성된 객체 값이어야 한다. 내장 함수 객체인 값은 CreateBuiltinFunction(steps, length, name, slots, realmRec, prototype)을 수행하여 생성한다. steps는 명세에 정의된 함수 정의, name은 함수의 "name" 프로퍼티 초기값, length"length" 초기값, slots는 함수의 내부 슬롯명(있으면), prototype은 함수의 [[Prototype]] 내부 슬롯의 명세 값이다. intrinsic 및 그 프로퍼티 생성 순서는 아직 생성되지 않은 객체에 의존하지 않도록 해야 한다.
  3. AddRestrictedFunctionProperties(realmRec.[[Intrinsics]].[[%Function.prototype%]], realmRec)을 수행한다.
  4. unused를 반환한다.

9.3.3 SetDefaultGlobalBindings ( realmRec )

추상 연산 SetDefaultGlobalBindings는 realmRec (Realm Record)를 인자로 받아 unused를 포함하는 정상 완료 또는 throw completion을 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. globalrealmRec.[[GlobalObject]]로 둔다.
  2. 19 절에 명시된 글로벌 객체의 각 프로퍼티에 대해,
    1. name프로퍼티 이름의 문자열 값으로 둔다.
    2. desc를 완전히 채워진 데이터 Property Descriptor로 둔다. 여기에는 프로퍼티에 대한 명시된 특성이 포함된다. 19.2, 19.3, 19.4에 나열된 프로퍼티의 경우 [[Value]] 특성 값은 realmRec의 해당 intrinsic 객체이다.
    3. DefinePropertyOrThrow(global, name, desc)를 수행한다.
  3. unused를 반환한다.

9.4 실행 컨텍스트

실행 컨텍스트는 ECMAScript 구현체가 코드의 런타임 평가를 추적하기 위해 사용하는 명세 장치입니다. 특정 시점에, 실제로 코드를 실행 중인 agent마다 최대 하나의 실행 컨텍스트만 존재할 수 있습니다. 이를 agent실행 중인 실행 컨텍스트라 합니다. 이 명세에서 실행 중인 실행 컨텍스트에 대한 모든 참조는 상위 agent실행 중인 실행 컨텍스트를 나타냅니다.

실행 컨텍스트 스택은 실행 컨텍스트들을 추적하는 데 사용됩니다. 실행 중인 실행 컨텍스트는 항상 이 스택의 맨 위 요소입니다. 현재 실행 중인 실행 컨텍스트와 연관된 실행 코드에서 아직 연관되지 않은 실행 코드로 제어가 이동할 때마다, 새 실행 컨텍스트가 생성되어 스택에 푸시되고 실행 중인 실행 컨텍스트가 됩니다.

실행 컨텍스트는 연관된 코드의 실행 진행을 추적하는 데 필요한 구현체 고유의 상태를 포함합니다. 각 실행 컨텍스트는 최소한 표 25에 나열된 상태 구성 요소를 가집니다.

표 25: 모든 실행 컨텍스트의 상태 구성 요소
구성 요소 목적
code evaluation state 실행 컨텍스트와 연관된 코드의 평가, 일시 중단, 재개를 수행하는 데 필요한 상태.
Function 실행 컨텍스트함수 객체의 코드를 평가 중이면, 이 구성 요소의 값은 해당 함수 객체입니다. 만약 Script 또는 Module의 코드를 평가 중이면, 값은 null입니다.
Realm 연관된 코드가 ECMAScript 리소스에 접근할 때 사용하는 Realm Record.
ScriptOrModule 연관된 코드가 기원한 Module Record 또는 Script Record. InitializeHostDefinedRealm에서 생성된 최초의 실행 컨텍스트처럼 기원 스크립트나 모듈이 없는 경우, 값은 null입니다.

Evaluation실행 중인 실행 컨텍스트에 의해 여러 정의된 지점에서 일시 중단될 수 있습니다. 일단 실행 중인 실행 컨텍스트가 일시 중단되면, 다른 실행 컨텍스트가 실행 중인 실행 컨텍스트가 되어 자신의 코드를 평가하기 시작할 수 있습니다. 이후 일시 중단된 실행 컨텍스트가 다시 실행 중인 실행 컨텍스트가 되어 코드 평가를 중단된 지점부터 재개할 수 있습니다. 실행 컨텍스트들 간의 실행 중인 실행 컨텍스트 상태의 전이는 보통 스택과 같은 후입선출(LIFO) 방식으로 발생합니다. 다만, 일부 ECMAScript 기능은 실행 중인 실행 컨텍스트의 비-LIFO 전이를 요구합니다.

실행 중인 실행 컨텍스트Realm 구성 요소 값을 현재 Realm Record라고도 합니다. 실행 중인 실행 컨텍스트의 Function 구성 요소는 활성 함수 객체라고도 합니다.

ECMAScript 코드 실행 컨텍스트표 26에 나열된 추가 상태 구성 요소를 가집니다.

표 26: ECMAScript 코드 실행 컨텍스트의 추가 상태 구성 요소
구성 요소 목적
LexicalEnvironment 실행 컨텍스트 내 코드에서 식별자 참조를 해결할 때 사용하는 환경 레코드.
VariableEnvironment 실행 컨텍스트 내에서 VariableStatement에 의해 생성된 바인딩을 보관하는 환경 레코드.
PrivateEnvironment 가장 가까운 포함 클래스 내 ClassElement에 의해 생성된 Private Name을 보관하는 PrivateEnvironment 레코드. 포함 클래스가 없으면 null.

실행 컨텍스트의 LexicalEnvironment, VariableEnvironment 구성 요소는 항상 환경 레코드입니다.

Generator의 평가를 나타내는 실행 컨텍스트는 표 27에 나열된 추가 상태 구성 요소를 가집니다.

표 27: Generator 실행 컨텍스트의 추가 상태 구성 요소
구성 요소 목적
Generator 실행 컨텍스트가 평가하는 Generator.

대부분의 상황에서 이 명세 내 알고리즘이 직접 다루는 것은 실행 중인 실행 컨텍스트 (즉, 실행 컨텍스트 스택의 맨 위)입니다. 따라서 “LexicalEnvironment”, “VariableEnvironment”라는 용어가 한정 없이 사용될 때는 실행 중인 실행 컨텍스트의 해당 구성 요소를 의미합니다.

실행 컨텍스트는 순수 명세 메커니즘으로, ECMAScript 구현의 실제 산출물과 반드시 대응하지 않습니다. ECMAScript 코드가 실행 컨텍스트를 직접 접근하거나 관찰하는 것은 불가능합니다.

9.4.1 GetActiveScriptOrModule ( )

추상 연산 GetActiveScriptOrModule은 인자가 없으며, Script Record, Module Record 또는 null을 반환합니다. 실행 중인 실행 컨텍스트를 기반으로 현재 실행 중인 스크립트 또는 모듈을 결정하는 데 사용됩니다. 호출 시 다음 단계를 수행합니다:

  1. 실행 컨텍스트 스택이 비어있으면 null을 반환한다.
  2. ec실행 컨텍스트 스택에서 ScriptOrModule 구성 요소가 null이 아닌 맨 위의 실행 컨텍스트로 둔다.
  3. 그런 실행 컨텍스트가 존재하지 않으면 null을 반환하고, 그렇지 않으면 ec의 ScriptOrModule을 반환한다.

9.4.2 ResolveBinding ( name [ , env ] )

추상 연산 ResolveBinding은 name (문자열) 및 선택적 env (환경 레코드 또는 undefined)를 인자로 받아, Reference Record를 포함하는 정상 완료 또는 throw completion을 반환합니다. 이 연산은 name의 바인딩을 결정하는 데 사용됩니다. env를 명시적으로 지정하면 해당 환경 레코드에서 바인딩을 탐색합니다. 호출 시 다음 단계를 수행합니다:

  1. env가 생략되었거나 envundefined라면,
    1. env실행 중인 실행 컨텍스트의 LexicalEnvironment로 설정한다.
  2. Assert: env환경 레코드임을 보장한다.
  3. strictIsStrict(현재 평가 중인 구문 생성 규칙)로 둔다.
  4. GetIdentifierReference(env, name, strict)를 반환한다.
참고

ResolveBinding의 결과는 항상 [[ReferencedName]] 필드가 nameReference Record입니다.

9.4.3 GetThisEnvironment ( )

추상 연산 GetThisEnvironment는 인자가 없으며 환경 레코드를 반환합니다. 현재 키워드 this의 바인딩을 제공하는 환경 레코드를 찾습니다. 호출 시 다음 단계를 수행합니다:

  1. env실행 중인 실행 컨텍스트의 LexicalEnvironment로 둔다.
  2. 반복,
    1. existsenv.HasThisBinding()으로 둔다.
    2. existstrue라면 env를 반환한다.
    3. outerenv.[[OuterEnv]]로 둔다.
    4. Assert: outernull이 아님을 보장한다.
    5. envouter로 설정한다.
참고

2 단계의 루프는 환경 리스트가 항상 this 바인딩을 가진 글로벌 환경에서 끝나므로 반드시 종료됩니다.

9.4.4 ResolveThisBinding ( )

추상 연산 ResolveThisBinding은 인자가 없으며 ECMAScript 언어 값을 포함하는 정상 완료 또는 throw completion을 반환합니다. 실행 중인 실행 컨텍스트의 LexicalEnvironment를 사용하여 키워드 this의 바인딩을 결정합니다. 호출 시 다음 단계를 수행합니다:

  1. envRecGetThisEnvironment()로 둔다.
  2. envRec.GetThisBinding()을 반환한다.

9.4.5 GetNewTarget ( )

추상 연산 GetNewTarget은 인자가 없으며 객체 또는 undefined를 반환합니다. 실행 중인 실행 컨텍스트의 LexicalEnvironment를 사용해 NewTarget 값을 결정합니다. 호출 시 다음 단계를 수행합니다:

  1. envRecGetThisEnvironment()로 둔다.
  2. Assert: envRec[[NewTarget]] 필드를 가지고 있음을 보장한다.
  3. envRec.[[NewTarget]]을 반환한다.

9.4.6 GetGlobalObject ( )

추상 연산 GetGlobalObject는 인자가 없으며 객체를 반환합니다. 현재 실행 중인 실행 컨텍스트가 사용하는 글로벌 객체를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. currentRealm현재 Realm Record로 둔다.
  2. currentRealm.[[GlobalObject]]를 반환한다.

9.5 잡과 잡을 큐에 넣는 호스트 연산

잡(Job)은 파라미터가 없는 추상 클로저(Abstract Closure)로, 다른 ECMAScript 계산이 현재 진행 중이 아닐 때 ECMAScript 계산을 시작합니다.

은 ECMAScript 호스트 환경에 의해 특정 에이전트에서 실행이 예약됩니다. 이 명세는 잡 예약을 위한 호스트 훅HostEnqueueGenericJob, HostEnqueueFinalizationRegistryCleanupJob, HostEnqueuePromiseJob, HostEnqueueTimeoutJob을 설명합니다. 이 명세의 호스트 훅은 잡 예약에 추가 제약을 가하는 방식에 따라 구성되어 있습니다. 호스트는 잡을 예약하는 추가 추상 연산을 정의할 수 있습니다. 이러한 연산은 추상 클로저realm(Realm Record 또는 null)를 인자로 받습니다. Realm Record가 제공되면, 이 연산들은 해당 realm을 소유하는 에이전트에서 미래의 어느 시점에 잡 실행을 예약합니다. realm 대신 null이 제공되면, 잡은 ECMAScript 코드를 실행하지 않습니다. 구현은 다음 요구사항을 따라야 합니다:

참고 1
호스트 환경의 스케줄링을 동일하게 처리할 필요는 없습니다. 예를 들어, 웹 브라우저와 Node.js는 Promise 처리 잡을 다른 작업보다 더 높은 우선순위로 취급합니다. 앞으로의 기능에서는 그렇게 높은 우선순위로 처리되지 않는 잡이 추가될 수도 있습니다.

특정 시점에 scriptOrModule(Script Record, Module Record 또는 null)이 다음 조건을 모두 만족하면 활성 스크립트 또는 모듈(active script or module)입니다:

특정 시점에 실행이 다음 조건을 모두 만족하면 ECMAScript 코드 평가 준비 상태(prepared to evaluate ECMAScript code)입니다:

참고 2

호스트 환경실행 컨텍스트 스택실행 컨텍스트를 푸시함으로써 코드 평가 준비 상태로 만들 수 있습니다. 구체적인 단계는 구현 정의입니다.

Realm의 구체적인 선택은 호스트 환경에 달려 있습니다. 이 초기 실행 컨텍스트Realm는 콜백 함수가 호출되기 전까지만 사용됩니다. Promise 핸들러 같은 관련 콜백 함수가 호출되면, 해당 호출은 자체적으로 실행 컨텍스트Realm를 푸시합니다.

특정 종류의 은 추가 준수 요구사항을 가집니다.

9.5.1 JobCallback 레코드

JobCallback 레코드Record 값으로, 함수 객체호스트 정의 값을 저장하는 데 사용됩니다. 을 통해 호스트가 큐에 넣는 함수 객체는 추가 호스트 정의 컨텍스트를 가질 수 있습니다. 그 상태를 전파하려면, 추상 클로저는 함수 객체를 직접 캡처하고 호출하지 말고, HostMakeJobCallbackHostCallJobCallback을 사용해야 합니다.

참고

예를 들어 WHATWG HTML 명세(https://html.spec.whatwg.org/)는 Promise 콜백의 incumbent settings object를 전파하기 위해 호스트 정의 값을 사용합니다.

JobCallback 레코드는 표 28에 나열된 필드를 가집니다.

표 28: JobCallback 레코드 필드
필드 명 의미
[[Callback]] 함수 객체 이 호출될 때 실행할 함수입니다.
[[HostDefined]] 임의의 값 (기본값 empty) 호스트가 사용하는 필드입니다.

9.5.2 HostMakeJobCallback ( callback )

호스트 정의 추상 연산 HostMakeJobCallback은 callback(함수 객체)를 인자로 받아 JobCallback 레코드를 반환합니다.

HostMakeJobCallback의 구현은 다음을 준수해야 합니다:

HostMakeJobCallback의 기본 구현은 호출 시 다음 단계를 수행합니다:

  1. JobCallback 레코드 { [[Callback]]: callback, [[HostDefined]]: empty }를 반환한다.

웹 브라우저가 아닌 ECMAScript 호스트는 HostMakeJobCallback의 기본 구현을 사용해야 합니다.

참고

이 연산은 콜백이 결국 예약·실행 책임이 있는 함수에 전달될 때 호출됩니다. 예를 들어 promise.then(thenAction)Promise.prototype.then을 호출할 때 thenAction에 대해 MakeJobCallback을 호출하며, 리액션 을 스케줄링할 때가 아닙니다.

9.5.3 HostCallJobCallback ( jobCallback, V, argumentsList )

호스트 정의 추상 연산 HostCallJobCallback은 jobCallback (JobCallback 레코드), V (ECMAScript 언어 값), argumentsList (List of ECMAScript 언어 값)을 인자로 받아, ECMAScript 언어 값을 포함하는 정상 완료 또는 throw completion을 반환합니다.

HostCallJobCallback의 구현은 다음을 준수해야 합니다:

  • Call(jobCallback.[[Callback]], V, argumentsList)를 수행하고 그 결과를 반환해야 합니다.
참고

이 요구사항은 호스트가 이 명세에서 정의한 함수 객체[[Call]] 동작을 변경할 수 없음을 의미합니다.

HostCallJobCallback의 기본 구현은 호출 시 다음 단계를 수행합니다:

  1. Assert: IsCallable(jobCallback.[[Callback]])가 true임을 보장한다.
  2. Call(jobCallback.[[Callback]], V, argumentsList)를 반환한다.

웹 브라우저가 아닌 ECMAScript 호스트는 HostCallJobCallback의 기본 구현을 사용해야 합니다.

9.5.4 HostEnqueueGenericJob ( job, realm )

호스트 정의 추상 연산 HostEnqueueGenericJob은 job( 추상 클로저), realm(Realm Record)를 인자로 받아 unused를 반환합니다. jobrealm이 소유한 에이전트realm에 예약합니다. 이 알고리즘에서 사용하는 추상 클로저는 우선순위나 순서 등 추가 제약 없이 예약되는 것을 의도합니다.

HostEnqueueGenericJob의 구현은 9.5의 요구사항을 따라야 합니다.

9.5.5 HostEnqueuePromiseJob ( job, realm )

호스트 정의 추상 연산 HostEnqueuePromiseJob은 job( 추상 클로저), realm(Realm Record 또는 null)를 인자로 받아 unused를 반환합니다. job을 미래의 어느 시점에 실행하도록 예약합니다. 이 알고리즘의 추상 클로저는 Promise 처리와 관련되거나 Promise 처리 연산과 같은 우선순위로 예약되는 것을 의도합니다.

HostEnqueuePromiseJob의 구현은 9.5의 요구사항과 다음을 따라야 합니다:

참고

NewPromiseResolveThenableJob이 반환하는 realm은 보통 then 함수 객체GetFunctionRealm을 호출한 결과입니다. NewPromiseReactionJob이 반환하는 realm은 핸들러가 undefined가 아니면 핸들러에 GetFunctionRealm을 호출한 결과, 핸들러가 undefinedrealmnull입니다. 둘 다 GetFunctionRealm이 비정상적으로 종료(예: 리보크된 Proxy에 호출)되면 realm은 호출 시점의 현재 Realm Record입니다. realmnull이면 사용자 ECMAScript 코드를 평가하지 않으며, 새로운 ECMAScript 객체(예: Error 객체)도 생성되지 않습니다. WHATWG HTML 명세(https://html.spec.whatwg.org/)는 예를 들어 realm을 스크립트 실행 가능 여부 점검, entry 개념 등에 사용합니다.

9.5.6 HostEnqueueTimeoutJob ( timeoutJob, realm, milliseconds )

호스트 정의 추상 연산 HostEnqueueTimeoutJob은 timeoutJob( 추상 클로저), realm(Realm Record), milliseconds(음이 아닌 유한 숫자)를 인자로 받아 unused를 반환합니다. timeoutJobrealm이 소유한 에이전트realm에서 최소 milliseconds 밀리초 후에 실행되도록 예약합니다.

HostEnqueueTimeoutJob의 구현은 9.5의 요구사항을 따라야 합니다.

9.6 에이전트

에이전트는 ECMAScript 실행 컨텍스트 집합, 실행 컨텍스트 스택, 실행 중인 실행 컨텍스트, 에이전트 레코드, 실행 스레드로 구성됩니다. 실행 스레드를 제외한 모든 구성 요소는 해당 에이전트에만 독점적으로 속합니다.

에이전트실행 스레드는 다른 에이전트와 독립적으로 해당 에이전트실행 컨텍스트에서 알고리즘 단계를 실행합니다. 단, 실행 스레드가 여러 에이전트에 의해 공유될 수는 있지만, 해당 스레드를 공유하는 에이전트 중 어느 것도 [[CanBlock]] 필드가 true에이전트 레코드를 가져서는 안 됩니다.

참고 1

예를 들어, 일부 웹 브라우저는 하나의 실행 스레드를 브라우저 창의 여러 무관한 탭에서 공유하기도 합니다.

에이전트실행 스레드가 알고리즘 단계를 실행하는 동안 그 에이전트는 해당 단계들의 상위 에이전트입니다. 이 단계들은 상위 에이전트를 사용해 에이전트가 보유한 명세 수준의 실행 객체들, 즉 실행 중인 실행 컨텍스트, 실행 컨텍스트 스택, 에이전트 레코드의 필드에 접근합니다.

에이전트 식별자(agent signifier)에이전트를 식별하기 위해 사용되는 전역적으로 유일한 불투명 값입니다.

표 29: 에이전트 레코드 필드
필드명 의미
[[LittleEndian]] 불리언 GetValueFromBufferSetValueInBuffer 알고리즘에서 isLittleEndian 파라미터가 필요할 때 계산되는 기본값입니다. 선택은 구현 정의이며, 구현에 가장 효율적인 대안을 선택해야 합니다. 일단 값이 관찰되면 변경될 수 없습니다.
[[CanBlock]] 불리언 에이전트가 블록할 수 있는지 여부를 결정합니다.
[[Signifier]] 에이전트 식별자 자신이 속한 에이전트 클러스터 내에서 에이전트를 유일하게 식별합니다.
[[IsLockFree1]] 불리언 1-바이트 값에 대한 원자적 연산이 lock-free라면 true, 아니면 false입니다.
[[IsLockFree2]] 불리언 2-바이트 값에 대한 원자적 연산이 lock-free라면 true, 아니면 false입니다.
[[IsLockFree8]] 불리언 8-바이트 값에 대한 원자적 연산이 lock-free라면 true, 아니면 false입니다.
[[CandidateExecution]] candidate execution 레코드 메모리 모델 참고.
[[KeptAlive]] List (객체 또는 심볼) 초기값은 새로운 빈 List로, 현재 이 끝날 때까지 생존해야 하는 객체/심볼 목록을 나타냅니다.
[[ModuleAsyncEvaluationCount]] 정수 초기값은 0이며, 비동기 또는 비동기 의존성이 있는 모듈의 [[AsyncEvaluationOrder]] 필드에 고유하게 증가하는 값을 할당하는 데 사용됩니다.

[[Signifier]], [[IsLockFree1]], [[IsLockFree2]]의 값은 에이전트 클러스터 내의 어떤 에이전트에라도 관찰되면 변경될 수 없습니다.

참고 2

[[IsLockFree1]][[IsLockFree2]]의 값은 반드시 하드웨어에 의해 결정되는 것은 아니며, 구현 선택에 따라 시간 및 ECMAScript 구현별로 달라질 수 있습니다.

[[IsLockFree4]] 필드는 없습니다. 4바이트 원자 연산은 항상 lock-free입니다.

실제로, 원자 연산이 어떤 종류의 락을 사용한다면 lock-free가 아닙니다. lock-free는 wait-free와는 다릅니다. lock-free 원자 연산을 완료하는 데 필요한 머신 스텝 수에 상한이 없습니다.

크기 n의 원자 접근이 lock-free여도, 크기 n의 비원자 접근의 (관측된) 원자성에 대해서는 아무것도 보장하지 않습니다. 비원자 접근은 여전히 여러 번의 별도 메모리 접근으로 수행될 수 있습니다. 자세한 내용은 ReadSharedMemoryWriteSharedMemory를 참고하세요.

참고 3

에이전트는 명세 메커니즘일 뿐이며, 실제 ECMAScript 구현의 어떤 구체적 산출물과 반드시 대응하지는 않습니다.

9.6.1 AgentSignifier ( )

추상 연산 AgentSignifier는 인자가 없으며 에이전트 식별자를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. AR상위 에이전트에이전트 레코드로 둔다.
  2. AR.[[Signifier]]를 반환한다.

9.6.2 AgentCanSuspend ( )

추상 연산 AgentCanSuspend는 인자가 없으며 불리언을 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. AR상위 에이전트에이전트 레코드로 둔다.
  2. AR.[[CanBlock]]을 반환한다.
참고

일부 환경에서는 특정 에이전트가 일시 정지(suspend)하는 것이 비합리적일 수 있습니다. 예를 들어, 웹 브라우저 환경에서는 문서의 메인 이벤트 처리 스레드는 일시 정지를 허용하지 않으면서 워커의 이벤트 처리 스레드는 허용할 수 있습니다.

9.6.3 IncrementModuleAsyncEvaluationCount ( )

추상 연산 IncrementModuleAsyncEvaluationCount는 인자가 없으며 정수를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. AR상위 에이전트에이전트 레코드로 둔다.
  2. countAR.[[ModuleAsyncEvaluationCount]]로 둔다.
  3. AR.[[ModuleAsyncEvaluationCount]]count + 1로 설정한다.
  4. count를 반환한다.
참고

이 값은 보류 중인 모듈들 간의 상대적인 평가 순서를 추적하는 데만 사용됩니다. 구현은 보류 중인 모듈이 없을 때 [[ModuleAsyncEvaluationCount]]를 0으로 눈에 띄지 않게 초기화할 수 있습니다.

9.7 에이전트 클러스터

에이전트 클러스터는 공유 메모리에서 동작하여 통신할 수 있는 에이전트의 최대 집합입니다.

참고 1

서로 다른 에이전트 내의 프로그램들은 명세되지 않은 방법으로 메모리를 공유할 수 있습니다. 최소한, SharedArrayBuffer의 백업 메모리는 클러스터 내의 에이전트들 간에 공유될 수 있습니다.

메시지 전달로는 통신할 수 있지만 메모리는 공유할 수 없는 에이전트가 있을 수 있습니다. 이들은 결코 같은 에이전트 클러스터에 속하지 않습니다.

모든 에이전트는 정확히 하나의 에이전트 클러스터에 속합니다.

참고 2

클러스터 내의 에이전트가 항상 동시에 살아 있을 필요는 없습니다. 에이전트 A가 또 다른 에이전트 B를 생성한 뒤 A가 종료되고, B에이전트 C를 생성했다고 합시다. 만약 AB와 메모리를 공유할 수 있고, BC와 메모리를 공유할 수 있다면, 세 에이전트는 같은 클러스터에 속합니다.

클러스터 내의 모든 에이전트는 각각의 에이전트 레코드[[LittleEndian]] 필드 값이 동일해야 합니다.

참고 3

에이전트 클러스터 내의 서로 다른 에이전트[[LittleEndian]] 값이 다르면, 멀티바이트 데이터의 공유 메모리 사용이 어려워집니다.

클러스터 내의 모든 에이전트는 각각의 에이전트 레코드[[IsLockFree1]] 필드 값이 동일해야 하며, [[IsLockFree2]] 필드도 마찬가지입니다.

클러스터 내의 모든 에이전트는 각각의 에이전트 레코드[[Signifier]] 값이 달라야 합니다.

임베딩(embedding)은 에이전트의 지식이나 협조 없이 에이전트의 진행을 중단(비활성화)하거나 재개(활성화)할 수 있습니다. 이럴 경우, 임베딩은 클러스터 내 일부 에이전트만 활성 상태로 두고 나머지 에이전트를 무기한 비활성화된 상태로 남겨두어서는 안 됩니다.

참고 4

이 제한의 목적은 다른 에이전트가 비활성화되어 있는 동안 어떤 에이전트가 교착 상태에 빠지거나 기아 상태에 빠지는 상황을 방지하기 위함입니다. 예를 들어, 문서와 독립적인 수명을 가진 HTML shared worker가, 그런 독립 문서의 dedicated worker와 메모리를 공유할 수 있도록 허용한다면, 그리고 문서와 그 dedicated worker가 dedicated worker가 락을 보유한 상태에서 비활성화된다면(예: 문서가 윈도우의 history에 푸시됨), shared worker가 그 락을 얻으려 하면 dedicated worker가 다시 활성화될 때까지(혹은 영원히) 대기하게 됩니다. 그 동안 다른 윈도우의 워커들이 shared worker에 접근하려 하면 기아 상태가 됩니다.

이 제한의 의미는 임베딩 내 같은 suspend/wake 집합에 속하지 않은 에이전트끼리는 메모리 공유가 불가능하다는 점입니다.

임베딩은 클러스터 내 다른 에이전트의 사전 지식이나 협조 없이 에이전트를 종료시킬 수 있습니다. 만약 에이전트가 자기 자신이나 클러스터 내 다른 에이전트의 프로그래밍적 동작이 아니라 클러스터 외부의 힘에 의해 종료된다면, 임베딩은 두 가지 전략 중 하나를 선택해야 합니다: 클러스터 내 모든 에이전트를 종료시키거나, 클러스터 내 남은 구성원이 종료 사실을 감지할 수 있도록 신뢰할 수 있는 API를 제공하고, 종료 데이터에는 종료된 에이전트를 식별할 수 있는 충분한 정보를 포함해야 합니다.

참고 5

이런 종료의 예시로는: 별도 프로세스에서 실행되는 에이전트를 운영 체제나 사용자가 종료시키는 경우, 임베딩 자체가 같은 프로세스 내에서 실행되는 에이전트를 종료시키는 경우(에이전트별 자원 관리로 에이전트가 runaway임이 감지됨) 등이 있습니다.

아래 명세 값과 그로부터 추이적으로 도달 가능한 값들은 정확히 하나의 에이전트 클러스터에 속합니다.

클러스터 내 어떤 에이전트에 의한 ECMAScript 코드 평가 이전에, 클러스터 내 모든 에이전트 레코드[[CandidateExecution]] 필드는 초기 candidate execution으로 설정됩니다. 초기 candidate execution빈 candidate execution으로, [[EventsRecords]] 필드는, 각 에이전트에 대해, [[AgentSignifier]] 필드가 해당 에이전트에이전트 식별자이고, [[EventList]][[AgentSynchronizesWith]] 필드가 빈 ListAgent Events Record를 포함하는 List입니다.

참고 6

에이전트 클러스터 내 모든 에이전트에이전트 레코드[[CandidateExecution]] 필드에 있는 같은 candidate execution을 공유합니다. candidate execution메모리 모델에서 사용하는 명세 메커니즘입니다.

참고 7

에이전트 클러스터는 명세 메커니즘일 뿐이며, ECMAScript 구현의 어떤 실제 산출물과 반드시 대응하지는 않습니다.

9.8 전진 진행(Forward Progress)

에이전트전진 진행(forward progress)한다는 것은 이 명세에 따라 평가 단계를 수행하는 것입니다.

에이전트실행 중인 실행 컨텍스트가 동기적으로, 그리고 무기한 외부 이벤트를 기다릴 때 블록(blocked) 상태가 됩니다. 이 의미에서 블록될 수 있는 것은 에이전트에이전트 레코드[[CanBlock]] 필드가 true인 경우뿐입니다. 비차단(unblocked) 에이전트는 블록되지 않은 에이전트입니다.

구현체는 다음을 보장해야 합니다:

참고

이와 메모리 모델의 라이브니스 보장은 모든 seq-cst 쓰기가 결국 모든 에이전트에서 관찰 가능해짐을 보장합니다.

9.9 WeakRef 및 FinalizationRegistry 대상의 처리 모델

9.9.1 목표

이 명세는 어떤 객체나 심볼도 가비지 컬렉션된다는 보장을 하지 않습니다. 라이브(live)하지 않은 객체나 심볼은 오랜 시간이 지난 뒤에 해제될 수도 있고, 전혀 해제되지 않을 수도 있습니다. 이 때문에, 이 명세는 가비지 컬렉션에 의해 트리거되는 동작을 설명할 때 "may"라는 용어를 사용합니다.

WeakRefFinalizationRegistry의 의미론은 특정 시점에 발생하는 두 연산에 기반합니다:

  • WeakRef.prototype.deref가 호출될 때, (만약 undefined가 반환되지 않는다면) 참조 대상은 살아 있게 유지되며, 이후의 동기적 접근도 동일한 값을 반환합니다. 이 목록은 ClearKeptObjects 추상 연산을 사용해 동기 작업이 완료될 때 재설정됩니다.
  • FinalizationRegistry에 등록된 객체나 심볼이 도달 불가능해질 때, FinalizationRegistry의 cleanup 콜백 호출이, 동기 ECMAScript 실행이 완료된 뒤, 결국 일어날 수 있습니다. FinalizationRegistry cleanup은 CleanupFinalizationRegistry 추상 연산으로 수행됩니다.

이들 동작(ClearKeptObjects 또는 CleanupFinalizationRegistry)은 동기 ECMAScript 실행을 중단할 수 없습니다. 호스트가 더 긴 동기 ECMAScript 실행을 조립할 수도 있으므로, 이 명세는 ClearKeptObjectsCleanupFinalizationRegistry 예약을 호스트 환경에 위임합니다.

일부 ECMAScript 구현은 백그라운드에서, 또는 ECMAScript가 유휴 상태일 때 동작하는 가비지 컬렉터를 포함합니다. 호스트 환경CleanupFinalizationRegistry의 스케줄을 제어하도록 하면, finalizer 작업을 실행하기 위해 ECMAScript 실행을 재개할 수 있으므로, 보유 중인 값을 해제하고 전체 메모리 사용량을 줄일 수 있습니다.

9.9.2 라이브니스(Liveness)

어떤 객체/심볼 집합 S에 대해 S에 대한 가상 WeakRef-무시(hypothetical WeakRef-oblivious) 실행이란, S의 원소를 참조 대상으로 하는 WeakRefDeref의 결과가 항상 undefined를 반환하는 실행입니다.

참고 1
WeakRef-oblivious와 liveness는 두 가지 개념을 포착합니다. 첫째, WeakRef 자체는 참조 대상을 살아 있게 만들지 않습니다. 둘째, 라이브니스의 순환(cycles)은 값이 live임을 의미하지 않습니다. 예를 들어, v의 라이브니스 판정이 WeakRef 참조 대상 r의 라이브니스 판정에 의존할 때, r의 라이브니스는 v의 라이브니스를 전제할 수 없습니다(순환 논증 불가).
참고 2
WeakRef-obliviousness는 순환을 고려하기 위해 개별 값이 아닌 객체/심볼의 집합에 대해 정의됩니다. 만약 개별 값에 대해 정의한다면, 순환 내의 WeakRef 참조 대상은 그 정체성이 오직 순환 내 다른 WeakRef 참조 대상을 통해서만 관찰될지라도 live로 간주될 것입니다.
참고 3
구어적으로, 어떤 객체나 심볼이 포함된 모든 집합이 live라면, 그 객체나 심볼이 live라고 말합니다.

실행 중 아무 시점에서, 객체/심볼 집합 S가 다음 조건 중 하나를 만족하면 live라고 간주합니다:

  • S의 어떤 원소라도 어떤 에이전트[[KeptAlive]] List에 포함되어 있다.
  • S 내의 어떤 값의 정체성이 관찰되는, S에 대해 유효한 미래 가상 WeakRef-oblivious 실행이 존재한다.
참고 4
두 번째 조건은, 어떤 값의 정체성이 non-WeakRef 수단으로 관찰될 수 있다면 live임을 포착하려는 의도입니다. 값의 정체성은 엄격 동등성 비교나, Map의 키로 사용되는 것을 관찰함으로써 관찰될 수 있습니다.
참고 5

객체나 심볼이 필드, 내부 슬롯, 프로퍼티에 존재한다는 사실만으로 해당 값이 live임을 의미하지 않습니다. 예를 들어, 해당 값이 프로그램에 다시 전달되지 않는다면 관찰될 수 없습니다.

이것은 WeakMap의 키, WeakSet의 멤버, 그리고 FinalizationRegistry Cell 레코드의 [[WeakRefTarget]], [[UnregisterToken]] 필드에 해당합니다.

위 정의는, WeakMap 내의 키가 live가 아니라면, 해당 값 또한 반드시 live일 필요가 없음을 의미합니다.

참고 6
라이브니스는 WeakRef 엔진이 비워서는 안 되는 최소 보장입니다. 여기 정의된 라이브니스는 판정 불능(undecidable)입니다. 실제로 엔진은 도달성(reachability) 등 보수적 근사치를 사용합니다. 구현의 재량이 큽니다.

9.9.3 실행

아무 시점에서, 객체/심볼 집합 Slive가 아니라면, ECMAScript 구현은 다음 단계를 원자적으로 수행할 수 있습니다:

  1. S의 각 원소 value에 대해,
    1. ref.[[WeakRefTarget]]value인 모든 WeakRef ref에 대해,
      1. ref.[[WeakRefTarget]]empty로 설정한다.
    2. fg.[[Cells]]cell이 있고 cell.[[WeakRefTarget]]value인 모든 FinalizationRegistry fg레코드 cell에 대해,
      1. cell.[[WeakRefTarget]]empty로 설정한다.
      2. 선택적으로, HostEnqueueFinalizationRegistryCleanupJob(fg)을 수행한다.
    3. map.[[WeakMapData]]r이 있고 r.[[Key]]value인 모든 WeakMap map레코드 r에 대해,
      1. r.[[Key]]empty로 설정한다.
      2. r.[[Value]]empty로 설정한다.
    4. set.[[WeakSetData]]value가 포함된 모든 WeakSet set에 대해,
      1. set.[[WeakSetData]]의 값이 value인 요소를 empty 값으로 교체한다.
참고 1

라이브니스 정의와 함께, 이 절은 구현체가 WeakRef에 대해 적용할 수 있는 최적화를 명시합니다.

객체의 정체성을 관찰하지 않고 객체에 접근하는 것이 가능합니다. 도달하지 않는 객체의 프로퍼티에 대한 데드 변수 제거, 스칼라 치환 등 최적화가 허용됩니다. 이 경우 해당 객체를 가리키는 WeakRef가 관찰 가능하게 비워지는 것도 허용됩니다.

반면, 객체의 정체성이 관찰 가능하고, 해당 객체가 WeakRef[[WeakRefTarget]] 내부 슬롯에 있을 때, rematerialization 등 WeakRef를 관찰 가능하게 비우는 최적화는 금지됩니다.

HostEnqueueFinalizationRegistryCleanupJob 호출은 선택적이므로, FinalizationRegistry에 등록된 객체가 반드시 FinalizationRegistrylive로 유지하는 것은 아닙니다. 구현체는 어떤 이유로든 FinalizationRegistry 콜백을 생략할 수 있습니다(예: FinalizationRegistry 자체가 dead가 되거나, 앱이 종료 중인 경우 등).

참고 2

구현체는 non-live 객체/심볼의 최대 집합에 대해 반드시 WeakRef를 비울 필요는 없습니다.

구현체가 live가 아닌 S 집합에 대해 WeakRef를 비우기로 선택했다면, 이 정의는 S의 모든 값에 대해 동시에 WeakRef를 비워야 함을 요구합니다. 즉, 구현체가 v를 가리키는 WeakRef만 비우고, 나머지 WeakRef를 그대로 두어 v의 값을 관찰할 수 있다면, 이는 준수(conformant)하지 않습니다.

9.9.4 호스트 훅

9.9.4.1 HostEnqueueFinalizationRegistryCleanupJob ( finalizationRegistry )

호스트 정의 추상 연산 HostEnqueueFinalizationRegistryCleanupJob은 finalizationRegistry (FinalizationRegistry)를 인자로 받아 unused를 반환합니다.

cleanupJobfinalizationRegistry를 캡처하고, 호출 시 다음 단계를 수행하는 파라미터 없는 추상 클로저로 둔다:

  1. cleanupResultCompletion(CleanupFinalizationRegistry(finalizationRegistry))로 둔다.
  2. cleanupResultabrupt completion이라면, 오류 리포팅을 위한 호스트 정의 단계를 수행한다.
  3. unused를 반환한다.

HostEnqueueFinalizationRegistryCleanupJob의 구현은 cleanupJob을 미래의 어느 시점에 실행하도록 예약합니다(가능하다면). 또한 9.5의 요구사항을 따라야 합니다.

9.10 ClearKeptObjects ( )

ClearKeptObjects 추상 연산은 인자를 받지 않으며 unused를 반환합니다. ECMAScript 구현은 동기적 ECMAScript 실행 시퀀스가 완료될 때 ClearKeptObjects를 호출해야 합니다. 호출 시 다음 단계를 수행합니다:

  1. agentRecord상위 에이전트에이전트 레코드로 둔다.
  2. agentRecord.[[KeptAlive]]를 새로운 빈 List로 설정한다.
  3. unused를 반환한다.

9.11 AddToKeptObjects ( value )

AddToKeptObjects 추상 연산은 value(객체 또는 심볼)를 인자로 받아 unused를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. agentRecord상위 에이전트에이전트 레코드로 둔다.
  2. agentRecord.[[KeptAlive]]value를 추가한다.
  3. unused를 반환한다.
참고
AddToKeptObjects 추상 연산이 대상 객체나 심볼로 호출되면, 대상은 ClearKeptObjects가 호출될 때까지 해당 대상을 강하게 참조하는 목록에 추가됩니다.

9.12 CleanupFinalizationRegistry ( finalizationRegistry )

CleanupFinalizationRegistry 추상 연산은 finalizationRegistry (FinalizationRegistry)를 인자로 받아 unused를 포함하는 정상 완료 또는 throw completion을 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. Assert: finalizationRegistry[[Cells]][[CleanupCallback]] 내부 슬롯을 가진다.
  2. callbackfinalizationRegistry.[[CleanupCallback]]로 둔다.
  3. finalizationRegistry.[[Cells]]레코드 cell이 있고 cell.[[WeakRefTarget]]empty인 동안, 구현체는 다음 단계를 수행할 수 있다:
    1. 그런 cell 중 아무거나 선택한다.
    2. finalizationRegistry.[[Cells]]에서 cell을 제거한다.
    3. HostCallJobCallback(callback, undefined, « cell.[[HeldValue]] »)를 수행한다.
  4. unused를 반환한다.

9.13 CanBeHeldWeakly ( v )

CanBeHeldWeakly 추상 연산은 v (ECMAScript 언어 값)를 인자로 받아 불리언을 반환합니다. v가 약 참조로 사용하기에 적합할 때에만 true를 반환합니다. 약 참조로 사용하기에 적합한 값만 WeakMap의 키, WeakSet의 요소, WeakRef의 대상, 또는 FinalizationRegistry의 대상 중 하나가 될 수 있습니다. 호출 시 다음 단계를 수행합니다:

  1. v객체라면, true를 반환한다.
  2. v심볼이고 KeyForSymbol(v)가 undefined라면, true를 반환한다.
  3. false를 반환한다.
참고

언어 정체성(language identity)이 없는 언어 값은 사전 참조 없이 나타날 수 있으므로 약 참조로 사용하기에 부적합합니다. Symbol.for로 생성된 Symbol 값은 다른 Symbol 값과 달리 언어 정체성이 없으므로 약 참조로 사용하기에 부적합합니다. well-known 심볼은 거의 수집되지 않지만, 그 수가 제한적이므로 다양한 구현 방식으로 관리 가능해 약 참조로 사용에 적합하다고 봅니다. 그러나 live WeakMap에 well-known 심볼에 연관된 값이 있다면, 해당 값은 거의 수집되지 않으며 구현체에 따라 메모리 리소스가 "누수"될 수 있습니다.

10 일반 객체와 익조틱 객체의 동작

10.1 일반 객체 내부 메서드와 내부 슬롯

모든 일반 객체[[Prototype]]이라는 내부 슬롯을 갖습니다. 이 내부 슬롯의 값은 null 또는 객체이며, 상속을 구현하는 데 사용됩니다. 만약 속성 P일반 객체 O에 존재하지 않고, [[Prototype]] 객체에 존재한다면, P[[Prototype]] 객체의 데이터 프로퍼티를 참조하는 경우, O는 get 접근에 대해 상속하여 P가 마치 O의 프로퍼티인 것처럼 동작합니다. P[[Prototype]] 객체의 쓰기 가능한 데이터 프로퍼티를 참조하면, O에서 P에 set 접근 시 OP라는 새로운 데이터 프로퍼티가 생성됩니다. P[[Prototype]] 객체의 쓰기 불가능한 데이터 프로퍼티를 참조하면, O에서 P에 set 접근이 실패합니다. P[[Prototype]] 객체의 접근자 프로퍼티를 참조하면, 접근자는 O에 대해 get/set 모두 상속됩니다.

모든 일반 객체는 불리언 값의 [[Extensible]] 내부 슬롯을 가지며, 이는 6.1.7.3에 명시된 확장성 관련 내부 메서드 불변식을 충족시키는 데 사용됩니다. 즉, 객체의 [[Extensible]] 내부 슬롯 값이 false로 설정되면, 더 이상 객체에 프로퍼티를 추가하거나, [[Prototype]] 내부 슬롯을 수정하거나, [[Extensible]] 값을 다시 true로 변경할 수 없습니다.

이후 알고리즘 설명에서, O일반 객체, P프로퍼티 키 값, V는 임의의 ECMAScript 언어 값, Desc프로퍼티 디스크립터 레코드라 가정합니다.

일반 객체 내부 메서드는 같은 이름의 추상 연산에 위임합니다. 만약 그러한 추상 연산이 다른 내부 메서드에 의존하면, 직접 추상 연산을 호출하는 대신 O에서 내부 메서드를 호출합니다. 이러한 의미론은 익조틱 객체에 대해 일반 객체 내부 메서드를 적용할 때, 오버라이드된 내부 메서드가 호출되도록 보장합니다.

10.1.1 [[GetPrototypeOf]] ( )

일반 객체 O[[GetPrototypeOf]] 내부 메서드는 인자를 받지 않으며, 객체 또는 null을 포함하는 정상 완료를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. OrdinaryGetPrototypeOf(O)를 반환한다.

10.1.1.1 OrdinaryGetPrototypeOf ( O )

OrdinaryGetPrototypeOf 추상 연산은 O (객체)를 인자로 받아, 객체 또는 null을 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. O.[[Prototype]]을 반환한다.

10.1.2 [[SetPrototypeOf]] ( V )

일반 객체 O[[SetPrototypeOf]] 내부 메서드는 V(객체 또는 null)를 인자로 받아, 불리언을 포함하는 정상 완료를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. OrdinarySetPrototypeOf(O, V)를 반환한다.

10.1.2.1 OrdinarySetPrototypeOf ( O, V )

OrdinarySetPrototypeOf 추상 연산은 O (객체), V (객체 또는 null)를 인자로 받아 불리언을 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. currentO.[[Prototype]]으로 둔다.
  2. SameValue(V, current)가 true라면, true를 반환한다.
  3. extensibleO.[[Extensible]]로 둔다.
  4. extensiblefalse라면, false를 반환한다.
  5. pV로 둔다.
  6. donefalse로 둔다.
  7. 반복: donefalse인 동안,
    1. pnull이면,
      1. donetrue로 설정한다.
    2. 그 외 SameValue(p, O)가 true이면,
      1. false를 반환한다.
    3. 그 외,
      1. p.[[GetPrototypeOf]]일반 객체 내부 메서드(10.1.1)가 아니라면, donetrue로 설정한다.
      2. 그 외, pp.[[Prototype]]으로 설정한다.
  8. O.[[Prototype]]V로 설정한다.
  9. true를 반환한다.
참고

7 단계의 루프는 일반 객체 정의의 [[GetPrototypeOf]], [[SetPrototypeOf]]만을 사용하는 객체만 포함된 프로토타입 체인에 순환이 없음을 보장합니다.

10.1.3 [[IsExtensible]] ( )

일반 객체 O[[IsExtensible]] 내부 메서드는 인자를 받지 않으며, 불리언을 포함하는 정상 완료를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. OrdinaryIsExtensible(O)를 반환한다.

10.1.3.1 OrdinaryIsExtensible ( O )

OrdinaryIsExtensible 추상 연산은 O (객체)를 인자로 받아 불리언을 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. O.[[Extensible]]을 반환한다.

10.1.4 [[PreventExtensions]] ( )

일반 객체 O[[PreventExtensions]] 내부 메서드는 인자를 받지 않으며, true를 포함하는 정상 완료를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. OrdinaryPreventExtensions(O)를 반환한다.

10.1.4.1 OrdinaryPreventExtensions ( O )

OrdinaryPreventExtensions 추상 연산은 O (객체)를 인자로 받아 true를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. O.[[Extensible]]false로 설정한다.
  2. true를 반환한다.

10.1.5 [[GetOwnProperty]] ( P )

일반 객체 O[[GetOwnProperty]] 내부 메서드는 P(프로퍼티 키)를 인자로 받아, 프로퍼티 디스크립터 또는 undefined를 포함하는 정상 완료를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. OrdinaryGetOwnProperty(O, P)를 반환한다.

10.1.5.1 OrdinaryGetOwnProperty ( O, P )

OrdinaryGetOwnProperty 추상 연산은 O(객체), P(프로퍼티 키)를 인자로 받아, 프로퍼티 디스크립터 또는 undefined를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. O에 키 P를 가진 자체 프로퍼티가 없으면, undefined를 반환한다.
  2. D를 필드가 없는 새 프로퍼티 디스크립터로 둔다.
  3. XO의 키 P를 가진 자체 프로퍼티로 둔다.
  4. X데이터 프로퍼티이면,
    1. D.[[Value]]X[[Value]] 특성 값으로 설정한다.
    2. D.[[Writable]]X[[Writable]] 특성 값으로 설정한다.
  5. 그 외,
    1. Assert: X접근자 프로퍼티이다.
    2. D.[[Get]]X[[Get]] 특성 값으로 설정한다.
    3. D.[[Set]]X[[Set]] 특성 값으로 설정한다.
  6. D.[[Enumerable]]X[[Enumerable]] 특성 값으로 설정한다.
  7. D.[[Configurable]]X[[Configurable]] 특성 값으로 설정한다.
  8. D를 반환한다.

10.1.6 [[DefineOwnProperty]] ( P, Desc )

일반 객체 O[[DefineOwnProperty]] 내부 메서드는 P(프로퍼티 키), Desc(프로퍼티 디스크립터)를 인자로 받아, 불리언을 포함하는 정상 완료 또는 throw completion을 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. OrdinaryDefineOwnProperty(O, P, Desc)를 반환한다.

10.1.6.1 OrdinaryDefineOwnProperty ( O, P, Desc )

OrdinaryDefineOwnProperty 추상 연산은 O(객체), P(프로퍼티 키), Desc(프로퍼티 디스크립터)를 인자로 받아, 불리언을 포함하는 정상 완료 또는 throw completion을 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. current를 ? O.[[GetOwnProperty]](P)로 둔다.
  2. extensible을 ? IsExtensible(O)로 둔다.
  3. ValidateAndApplyPropertyDescriptor(O, P, extensible, Desc, current)를 반환한다.

10.1.6.2 IsCompatiblePropertyDescriptor ( Extensible, Desc, Current )

IsCompatiblePropertyDescriptor 추상 연산은 Extensible(불리언), Desc(프로퍼티 디스크립터), Current(프로퍼티 디스크립터 또는 undefined)를 인자로 받아 불리언을 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. ValidateAndApplyPropertyDescriptor(undefined, "", Extensible, Desc, Current)를 반환한다.

10.1.6.3 ValidateAndApplyPropertyDescriptor ( O, P, extensible, Desc, current )

추상 연산 ValidateAndApplyPropertyDescriptor는 O (객체 또는 undefined), P (프로퍼티 키), extensible (불리언), Desc (프로퍼티 디스크립터), current (프로퍼티 디스크립터 또는 undefined)를 인자로 받고, 불리언을 반환한다. Desc가 지정된 extensibility와 현재 프로퍼티 current를 가진 객체의 프로퍼티로써 적용 가능하여 불변성을 유지할 수 있을 때, 그리고 그 경우에만 true를 반환한다. 그런 적용이 가능하고 Oundefined가 아니면 프로퍼티 이름 P에 대해 실제로 적용한다(필요하다면 생성). 호출 시 다음 단계를 수행한다:

  1. Assert: P프로퍼티 키이다.
  2. currentundefined라면,
    1. extensiblefalse라면 false를 반환한다.
    2. Oundefined라면 true를 반환한다.
    3. IsAccessorDescriptor(Desc) 가 true라면,
      1. 객체 O에 이름이 P인 자신의 접근자 프로퍼티를 생성한다. 이 프로퍼티의 [[Get]], [[Set]], [[Enumerable]], [[Configurable]] 속성은 Desc에 해당 필드가 있으면 그 값으로, 없으면 기본값으로 설정한다.
    4. 그 외의 경우,
      1. 객체 O에 이름이 P인 자신의 데이터 프로퍼티를 생성한다. 이 프로퍼티의 [[Value]], [[Writable]], [[Enumerable]], [[Configurable]] 속성은 Desc에 해당 필드가 있으면 그 값으로, 없으면 기본값으로 설정한다.
    5. true를 반환한다.
  3. Assert: current모든 필드가 채워진 프로퍼티 디스크립터이다.
  4. Desc가 아무 필드도 갖고 있지 않으면 true를 반환한다.
  5. current.[[Configurable]]false라면,
    1. Desc[[Configurable]] 필드가 있고 Desc.[[Configurable]]true라면 false를 반환한다.
    2. Desc[[Enumerable]] 필드가 있고 Desc.[[Enumerable]]current.[[Enumerable]]와 다르면 false를 반환한다.
    3. IsGenericDescriptor(Desc) 가 false이고, IsAccessorDescriptor(Desc) 가 IsAccessorDescriptor(current)와 다르면 false를 반환한다.
    4. IsAccessorDescriptor(current) 가 true라면,
      1. Desc[[Get]] 필드가 있고 SameValue(Desc.[[Get]], current.[[Get]])가 false라면 false를 반환한다.
      2. Desc[[Set]] 필드가 있고 SameValue(Desc.[[Set]], current.[[Set]])가 false라면 false를 반환한다.
    5. 그 외에 current.[[Writable]]false라면,
      1. Desc[[Writable]] 필드가 있고 Desc.[[Writable]]true라면 false를 반환한다.
      2. 참고: SameValueNaN 값에 대해 true를 반환하지만, 다른 방식으로는 구분될 수 있다. 여기서 반환하는 것은 객체 O의 기존 프로퍼티가 변경되지 않음을 보장한다.
      3. Desc[[Value]] 필드가 있으면, SameValue(Desc.[[Value]], current.[[Value]])를 반환한다.
  6. Oundefined가 아니면,
    1. IsDataDescriptor(current) 가 true이고 IsAccessorDescriptor(Desc) 가 true라면,
      1. Desc[[Configurable]] 필드가 있으면 configurableDesc.[[Configurable]]로, 없으면 current.[[Configurable]]로 둔다.
      2. Desc[[Enumerable]] 필드가 있으면 enumerableDesc.[[Enumerable]]로, 없으면 current.[[Enumerable]]로 둔다.
      3. 객체 O의 이름이 P인 프로퍼티를 접근자 프로퍼티로 교체한다. [[Configurable]][[Enumerable]] 속성은 각각 configurableenumerable로, [[Get]][[Set]] 속성은 Desc에 해당 필드가 있으면 그 값, 없으면 기본값으로 설정한다.
    2. 그 외에 IsAccessorDescriptor(current) 가 true이고 IsDataDescriptor(Desc) 가 true라면,
      1. Desc[[Configurable]] 필드가 있으면 configurableDesc.[[Configurable]]로, 없으면 current.[[Configurable]]로 둔다.
      2. Desc[[Enumerable]] 필드가 있으면 enumerableDesc.[[Enumerable]]로, 없으면 current.[[Enumerable]]로 둔다.
      3. 객체 O의 이름이 P인 프로퍼티를 데이터 프로퍼티로 교체한다. [[Configurable]][[Enumerable]] 속성은 각각 configurableenumerable로, [[Value]][[Writable]] 속성은 Desc에 해당 필드가 있으면 그 값, 없으면 기본값으로 설정한다.
    3. 그 외의 경우,
      1. Desc의 각 필드에 대해, 객체 O의 이름이 P인 프로퍼티의 해당 속성을 그 값으로 설정한다.
  7. true를 반환한다.

10.1.7 [[HasProperty]] ( P )

일반 객체 O[[HasProperty]] 내부 메서드는 P (프로퍼티 키)를 인자로 받아, 불리언을 포함하는 정상 완료 또는 throw completion을 반환한다. 호출 시 다음 단계를 수행한다:

  1. OrdinaryHasProperty(O, P)를 반환한다.

10.1.7.1 OrdinaryHasProperty ( O, P )

OrdinaryHasProperty 추상 연산은 O (객체)와 P (프로퍼티 키)를 인자로 받아, 불리언을 포함하는 정상 완료 또는 throw completion을 반환한다. 호출 시 다음 단계를 수행한다:

  1. hasOwn을 ? O.[[GetOwnProperty]](P)로 둔다.
  2. hasOwnundefined가 아니면 true를 반환한다.
  3. parent를 ? O.[[GetPrototypeOf]]()로 둔다.
  4. parentnull이 아니면,
    1. parent.[[HasProperty]](P)를 반환한다.
  5. false를 반환한다.

10.1.8 [[Get]] ( P, Receiver )

일반 객체 O[[Get]] 내부 메서드는 P (프로퍼티 키), Receiver (ECMAScript 언어 값)를 인자로 받아, ECMAScript 언어 값를 포함하는 정상 완료 또는 throw completion을 반환한다. 호출 시 다음 단계를 수행한다:

  1. OrdinaryGet(O, P, Receiver)를 반환한다.

10.1.8.1 OrdinaryGet ( O, P, Receiver )

OrdinaryGet 추상 연산은 O (객체), P (프로퍼티 키), Receiver (ECMAScript 언어 값)를 인자로 받아, ECMAScript 언어 값를 포함하는 정상 완료 또는 throw completion을 반환한다. 호출 시 다음 단계를 수행한다:

  1. desc를 ? O.[[GetOwnProperty]](P)로 둔다.
  2. descundefined이면,
    1. parent를 ? O.[[GetPrototypeOf]]()로 둔다.
    2. parentnull이면 undefined를 반환한다.
    3. parent.[[Get]](P, Receiver)를 반환한다.
  3. IsDataDescriptor(desc) 가 true이면 desc.[[Value]]를 반환한다.
  4. Assert: IsAccessorDescriptor(desc) 가 true이다.
  5. getterdesc.[[Get]]로 둔다.
  6. getterundefined이면 undefined를 반환한다.
  7. Call(getter, Receiver)를 반환한다.

10.1.9 [[Set]] ( P, V, Receiver )

일반 객체 O[[Set]] 내부 메서드는 P (프로퍼티 키), V (ECMAScript 언어 값), Receiver (ECMAScript 언어 값)를 인자로 받아, 불리언을 포함하는 정상 완료 또는 throw completion을 반환한다. 호출 시 다음 단계를 수행한다:

  1. OrdinarySet(O, P, V, Receiver)를 반환한다.

10.1.9.1 OrdinarySet ( O, P, V, Receiver )

OrdinarySet 추상 연산은 O (객체), P (프로퍼티 키), V (ECMAScript 언어 값), Receiver (ECMAScript 언어 값)를 인자로 받아, 불리언을 포함하는 정상 완료 또는 throw completion을 반환한다. 호출 시 다음 단계를 수행한다:

  1. ownDesc를 ? O.[[GetOwnProperty]](P)로 둔다.
  2. OrdinarySetWithOwnDescriptor(O, P, V, Receiver, ownDesc)를 반환한다.

10.1.9.2 OrdinarySetWithOwnDescriptor ( O, P, V, Receiver, ownDesc )

OrdinarySetWithOwnDescriptor 추상 연산은 O (객체), P (프로퍼티 키), V (ECMAScript 언어 값), Receiver (ECMAScript 언어 값), ownDesc (프로퍼티 디스크립터 또는 undefined)를 인자로 받아, 불리언을 포함하는 정상 완료 또는 throw completion을 반환한다. 호출 시 다음 단계를 수행한다:

  1. ownDescundefined라면,
    1. parent를 ? O.[[GetPrototypeOf]]()로 둔다.
    2. parentnull이 아니면,
      1. parent.[[Set]](P, V, Receiver)를 반환한다.
    3. 그 외의 경우,
      1. ownDesc를 PropertyDescriptor { [[Value]]: undefined, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }로 설정한다.
  2. IsDataDescriptor(ownDesc) 가 true라면,
    1. ownDesc.[[Writable]]false이면 false를 반환한다.
    2. Receiver객체가 아니면 false를 반환한다.
    3. existingDescriptor를 ? Receiver.[[GetOwnProperty]](P)로 둔다.
    4. existingDescriptorundefined가 아니면,
      1. IsAccessorDescriptor(existingDescriptor) 가 true이면 false를 반환한다.
      2. existingDescriptor.[[Writable]]false이면 false를 반환한다.
      3. valueDesc를 PropertyDescriptor { [[Value]]: V }로 둔다.
      4. Receiver.[[DefineOwnProperty]](P, valueDesc)를 반환한다.
    5. 그 외의 경우,
      1. Assert: Receiver 에는 현재 P 프로퍼티가 없다.
      2. CreateDataProperty(Receiver, P, V)를 반환한다.
  3. Assert: IsAccessorDescriptor(ownDesc) 가 true이다.
  4. setterownDesc.[[Set]]로 둔다.
  5. setterundefined이면 false를 반환한다.
  6. Call(setter, Receiver, « V »)를 수행한다.
  7. true를 반환한다.

10.1.10 [[Delete]] ( P )

일반 객체 O[[Delete]] 내부 메서드는 P (프로퍼티 키)를 인자로 받고, 불리언을 포함하는 정상 완료 또는 throw completion을 반환한다. 호출 시 다음 단계를 수행한다:

  1. OrdinaryDelete(O, P)를 반환한다.

10.1.10.1 OrdinaryDelete ( O, P )

OrdinaryDelete 추상 연산은 O (객체)와 P (프로퍼티 키)를 인자로 받아, 불리언을 포함하는 정상 완료 또는 throw completion을 반환한다. 호출 시 다음 단계를 수행한다:

  1. desc를 ? O.[[GetOwnProperty]](P)로 둔다.
  2. descundefined이면 true를 반환한다.
  3. desc.[[Configurable]]true이면,
    1. O에서 이름이 P인 자신의 프로퍼티를 제거한다.
    2. true를 반환한다.
  4. false를 반환한다.

10.1.11 [[OwnPropertyKeys]] ( )

일반 객체 O[[OwnPropertyKeys]] 내부 메서드는 인자를 받지 않으며, 프로퍼티 키의 리스트를 포함하는 정상 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. OrdinaryOwnPropertyKeys(O)를 반환한다.

10.1.11.1 OrdinaryOwnPropertyKeys ( O )

OrdinaryOwnPropertyKeys 추상 연산은 O (객체)를 인자로 받아, 프로퍼티 키리스트를 반환한다. 호출 시 다음 단계를 수행한다:

  1. keys를 새로운 빈 List로 둔다.
  2. O의 각 자신의 프로퍼티 키 P 중, P배열 인덱스인 경우, 숫자 인덱스 오름차순으로,
    1. Pkeys에 추가한다.
  3. O의 각 자신의 프로퍼티 키 P 중, P문자열이고 배열 인덱스가 아닌 경우, 프로퍼티 생성 시점 오름차순으로,
    1. Pkeys에 추가한다.
  4. O의 각 자신의 프로퍼티 키 P 중, P심볼인 경우, 프로퍼티 생성 시점 오름차순으로,
    1. Pkeys에 추가한다.
  5. keys를 반환한다.

10.1.12 OrdinaryObjectCreate ( proto [ , additionalInternalSlotsList ] )

OrdinaryObjectCreate 추상 연산은 proto (객체 또는 null), 선택적 additionalInternalSlotsList (내부 슬롯 이름의 리스트)를 인자로 받아 객체를 반환한다. 이는 새로운 일반 객체의 런타임 생성을 명세하는 데 사용된다. additionalInternalSlotsList에는 [[Prototype]], [[Extensible]] 외에 객체의 일부로 정의되어야 하는 추가 내부 슬롯의 이름이 포함된다. additionalInternalSlotsList가 생략되면, 새로운 빈 List가 사용된다. 호출 시 다음 단계를 수행한다:

  1. internalSlotsList를 « [[Prototype]], [[Extensible]] »로 둔다.
  2. additionalInternalSlotsList가 있으면, internalSlotsList리스트 연결 결과(internalSlotsList + additionalInternalSlotsList)로 설정한다.
  3. OMakeBasicObject(internalSlotsList)로 둔다.
  4. O.[[Prototype]]proto로 설정한다.
  5. O를 반환한다.
참고

OrdinaryObjectCreate는 MakeBasicObject만 호출하는 것처럼 보이지만, 이 연산을 사용하는 것은 일반 객체(exotic이 아님)를 생성하려는 의도를 명확히 전달합니다. 따라서, 이 명세 내에서 OrdinaryObjectCreate를 호출한 후 그 객체의 내부 메서드를 변경해서 exotic으로 만드는 알고리즘은 없습니다. exotic 객체를 생성하는 연산은 직접 MakeBasicObject를 호출합니다.

10.1.13 OrdinaryCreateFromConstructor ( constructor, intrinsicDefaultProto [ , internalSlotsList ] )

OrdinaryCreateFromConstructor 추상 연산은 constructor (함수 객체), intrinsicDefaultProto (문자열), 선택적 internalSlotsList (내부 슬롯 이름의 리스트)를 인자로 받아, 객체를 포함하는 정상 완료 또는 throw completion을 반환한다. 이는 [[Prototype]] 값을 constructor"prototype" 프로퍼티에서 가져오고, 없으면 intrinsicDefaultProto로 지정된 intrinsic을 사용하는 일반 객체를 생성한다. internalSlotsList에는 객체의 일부로 정의해야 하는 추가 내부 슬롯의 이름이 들어있다. internalSlotsList가 생략되면, 새로운 빈 List가 사용된다. 호출 시 다음 단계를 수행한다:

  1. Assert: intrinsicDefaultProto는 명세에서 정의한 intrinsic 객체의 이름이다. 해당 객체는 객체의 [[Prototype]] 값으로 사용하도록 지정된 intrinsic이어야 한다.
  2. proto를 ? GetPrototypeFromConstructor(constructor, intrinsicDefaultProto)로 둔다.
  3. internalSlotsList가 있으면 slotsListinternalSlotsList로 둔다.
  4. 그 외에는 slotsList를 새로운 빈 List로 둔다.
  5. OrdinaryObjectCreate(proto, slotsList)를 반환한다.

10.1.14 GetPrototypeFromConstructor ( constructor, intrinsicDefaultProto )

GetPrototypeFromConstructor 추상 연산은 constructor (함수 객체), intrinsicDefaultProto (문자열)를 인자로 받아, 객체를 포함하는 정상 완료 또는 throw completion을 반환한다. 이는 특정 constructor에 대해 객체를 만들 때 사용할 [[Prototype]] 값을 결정한다. 값은 constructor"prototype" 프로퍼티에서 가져오고, 없으면 intrinsicDefaultProto로 지정된 intrinsic이 사용된다. 호출 시 다음 단계를 수행한다:

  1. Assert: intrinsicDefaultProto는 명세에서 정의한 intrinsic 객체의 이름이다. 해당 객체는 객체의 [[Prototype]] 값으로 사용하도록 지정된 intrinsic이어야 한다.
  2. proto를 ? Get(constructor, "prototype")로 둔다.
  3. proto객체가 아니면,
    1. realm을 ? GetFunctionRealm(constructor)로 둔다.
    2. protorealmintrinsicDefaultProto 이름의 intrinsic 객체로 설정한다.
  4. proto를 반환한다.
참고

constructor[[Prototype]] 값을 제공하지 않으면, 사용되는 기본값은 realm에서 가져오며, 실행 중인 실행 컨텍스트에서 가져오지 않는다.

10.1.15 RequireInternalSlot ( O, internalSlot )

RequireInternalSlot 추상 연산은 O (ECMAScript 언어 값), internalSlot (내부 슬롯 이름)을 인자로 받아, unused를 포함하는 정상 완료 또는 throw completion을 반환한다. O객체가 아니거나 해당 내부 슬롯이 없으면 예외를 던진다. 호출 시 다음 단계를 수행한다:

  1. O객체가 아니면 TypeError 예외를 던진다.
  2. OinternalSlot 내부 슬롯이 없으면 TypeError 예외를 던진다.
  3. unused를 반환한다.

10.2 ECMAScript 함수 객체

ECMAScript 함수 객체는 렉시컬 환경을 닫아 매개변수를 가진 ECMAScript 코드를 캡슐화하고, 그 코드의 동적 평가를 지원합니다. ECMAScript 함수 객체일반 객체이며, 다른 일반 객체와 동일한 내부 슬롯과 내부 메서드를 가집니다. ECMAScript 함수 객체의 코드는 엄격 모드 코드 (11.2.2) 또는 비엄격 코드일 수 있습니다. ECMAScript 함수 객체 중 그 코드가 엄격 모드 코드인 것을 엄격 함수라 합니다. 코드가 엄격 모드 코드가 아닌 것은 비엄격 함수라 합니다.

[[Extensible]][[Prototype]] 외에, ECMAScript 함수 객체표 30에 나열된 내부 슬롯도 가집니다.

표 30: ECMAScript 함수 객체의 내부 슬롯
내부 슬롯 타입 설명
[[Environment]] 환경 레코드 함수가 닫힌 환경 레코드. 함수 코드 평가 시 외부 환경으로 사용됩니다.
[[PrivateEnvironment]] PrivateEnvironment 레코드 또는 null 함수가 닫힌 PrivateEnvironment 레코드. 이 함수가 클래스 내부에 있지 않으면 null입니다. 내부 클래스 코드 평가 시 외부 PrivateEnvironment로 사용됩니다.
[[FormalParameters]] 파스 노드 함수의 형식적 매개변수 목록을 정의하는 소스 텍스트의 루트 파스 노드입니다.
[[ECMAScriptCode]] 파스 노드 함수 본문을 정의하는 소스 텍스트의 루트 파스 노드입니다.
[[ConstructorKind]] base 또는 derived 함수가 파생 클래스 생성자인지 여부입니다.
[[Realm]] Realm Record 함수가 생성된 realm이며, 함수 평가 시 접근되는 intrinsic 객체를 제공합니다.
[[ScriptOrModule]] Script Record 또는 Module Record 함수가 생성된 스크립트 또는 모듈입니다.
[[ThisMode]] lexical, strict, 또는 global 함수의 형식 매개변수 및 코드 본문 내에서 this 참조가 해석되는 방식을 정의합니다. lexicalthis가 렉시컬 상위 함수의 this 값을 참조함을 의미합니다. strict는 함수 호출 시 제공된 this 값을 그대로 사용함을 의미합니다. globalthis 값이 undefined 또는 null이면 글로벌 객체로 해석하고, 그 외의 값은 ToObject를 거쳐 객체로 변환합니다.
[[Strict]] 불리언 true엄격 함수, false비엄격 함수입니다.
[[HomeObject]] 객체 함수가 super를 사용할 경우, super 프로퍼티 탐색이 시작되는 객체의 [[GetPrototypeOf]]를 제공합니다.
[[SourceText]] 유니코드 코드 포인트의 시퀀스 함수를 정의하는 소스 텍스트입니다.
[[Fields]] 레코드 리스트 (ClassFieldDefinition 레코드) 함수가 클래스일 경우, 클래스의 비정적 필드 및 해당 이니셜라이저를 나타내는 레코드 리스트입니다.
[[PrivateMethods]] 레코드 리스트 (PrivateElement) 함수가 클래스일 경우, 클래스의 비정적 private 메서드 및 접근자를 나타내는 리스트입니다.
[[ClassFieldInitializerName]] 문자열, 심볼, Private Name, 또는 empty 함수가 클래스 필드의 이니셜라이저로 생성된 경우, 필드의 NamedEvaluation에 사용할 이름입니다. 그렇지 않으면 empty입니다.
[[IsClassConstructor]] 불리언 함수가 클래스 생성자인지 나타냅니다. (true이면 함수의 [[Call]]을 호출하는 즉시 TypeError 예외가 발생합니다.)

모든 ECMAScript 함수 객체는 여기에 정의된 [[Call]] 내부 메서드를 가집니다. 생성자이기도 한 ECMAScript 함수는 [[Construct]] 내부 메서드도 추가로 가집니다.

10.2.1 [[Call]] ( thisArgument, argumentsList )

ECMAScript 함수 객체 F[[Call]] 내부 메서드는 thisArgument (ECMAScript 언어 값), argumentsList (ECMAScript 언어 값 리스트)를 인자로 받아, ECMAScript 언어 값를 포함하는 정상 완료 또는 throw completion을 반환한다. 호출 시 다음 단계를 수행한다:

  1. callerContext실행 중인 실행 컨텍스트로 둔다.
  2. calleeContextPrepareForOrdinaryCall(F, undefined)로 둔다.
  3. Assert: calleeContext가 이제 실행 중인 실행 컨텍스트임을 보장한다.
  4. F.[[IsClassConstructor]]true이면,
    1. error를 새로 생성된 TypeError 객체로 둔다.
    2. 참고: errorcalleeContext 내에서 F와 연관된 Realm Record에서 생성된다.
    3. calleeContext실행 컨텍스트 스택에서 제거하고, callerContext실행 중인 실행 컨텍스트로 복원한다.
    4. ThrowCompletion(error)를 반환한다.
  5. OrdinaryCallBindThis(F, calleeContext, thisArgument)를 수행한다.
  6. resultCompletion(OrdinaryCallEvaluateBody(F, argumentsList))로 둔다.
  7. calleeContext실행 컨텍스트 스택에서 제거하고, callerContext실행 중인 실행 컨텍스트로 복원한다.
  8. resultreturn completion이면 result.[[Value]]를 반환한다.
  9. Assert: resultthrow completion임을 보장한다.
  10. result를 반환한다.
참고

실행 컨텍스트 스택에서 calleeContext7단계에서 제거될 때, accessible Generator에 의해 나중에 재개(resume)될 수 있도록 일시 정지(suspend) 상태라면 파괴되어서는 안 됩니다.

10.2.1.1 PrepareForOrdinaryCall ( F, newTarget )

추상 연산 PrepareForOrdinaryCall은 F (ECMAScript 함수 객체), newTarget (객체 또는 undefined)를 인자로 받아 실행 컨텍스트를 반환한다. 호출 시 다음 단계를 수행한다:

  1. callerContext실행 중인 실행 컨텍스트로 둔다.
  2. calleeContext를 새로운 ECMAScript 코드 실행 컨텍스트로 둔다.
  3. calleeContext의 Function을 F로 설정한다.
  4. calleeRealmF.[[Realm]]으로 둔다.
  5. calleeContextRealmcalleeRealm으로 설정한다.
  6. calleeContext의 ScriptOrModule을 F.[[ScriptOrModule]]로 설정한다.
  7. localEnvNewFunctionEnvironment(F, newTarget)로 둔다.
  8. calleeContext의 LexicalEnvironment를 localEnv로 설정한다.
  9. calleeContext의 VariableEnvironment를 localEnv로 설정한다.
  10. calleeContext의 PrivateEnvironment를 F.[[PrivateEnvironment]]로 설정한다.
  11. callerContext가 이미 일시 정지(suspended) 상태가 아니면, callerContext를 일시 정지시킨다.
  12. calleeContext실행 컨텍스트 스택에 푸시한다; calleeContext는 이제 실행 중인 실행 컨텍스트이다.
  13. 참고: 이 시점 이후 생성된 모든 예외 객체는 calleeRealm과 연관된다.
  14. calleeContext를 반환한다.

10.2.1.2 OrdinaryCallBindThis ( F, calleeContext, thisArgument )

추상 연산 OrdinaryCallBindThis는 F (ECMAScript 함수 객체), calleeContext (실행 컨텍스트), thisArgument (ECMAScript 언어 값)을 인자로 받아 unused를 반환한다. 호출 시 다음 단계를 수행한다:

  1. thisModeF.[[ThisMode]]로 둔다.
  2. thisModelexical이면 unused를 반환한다.
  3. calleeRealmF.[[Realm]]으로 둔다.
  4. localEnvcalleeContext의 LexicalEnvironment로 둔다.
  5. thisModestrict이면,
    1. thisValuethisArgument로 둔다.
  6. 그 외의 경우,
    1. thisArgumentundefinednull이면,
      1. globalEnvcalleeRealm.[[GlobalEnv]]로 둔다.
      2. Assert: globalEnvGlobal Environment Record이다.
      3. thisValueglobalEnv.[[GlobalThisValue]]로 둔다.
    2. 그 외에는,
      1. thisValue를 ! ToObject(thisArgument)로 둔다.
      2. 참고: ToObjectcalleeRealm을 사용해 래퍼 객체를 생성한다.
  7. Assert: localEnvFunction Environment Record이다.
  8. Assert: 다음 단계는 localEnv.[[ThisBindingStatus]]initialized가 아니므로 abrupt completion을 반환하지 않는다.
  9. BindThisValue(localEnv, thisValue)를 수행한다.
  10. unused를 반환한다.

10.2.1.3 Runtime Semantics: EvaluateBody

구문 지시 연산(syntax-directed operation) EvaluateBody는 functionObject (ECMAScript 함수 객체), argumentsList (ECMAScript 언어 값 리스트)를 인자로 받아 return completion 또는 throw completion을 반환한다. 아래 프로덕션별로 정의된다:

FunctionBody : FunctionStatementList
  1. EvaluateFunctionBody of FunctionBody with arguments functionObject and argumentsList를 반환한다.
ConciseBody : ExpressionBody
  1. EvaluateConciseBody of ConciseBody with arguments functionObject and argumentsList를 반환한다.
GeneratorBody : FunctionBody
  1. EvaluateGeneratorBody of GeneratorBody with arguments functionObject and argumentsList를 반환한다.
AsyncGeneratorBody : FunctionBody
  1. EvaluateAsyncGeneratorBody of AsyncGeneratorBody with arguments functionObject and argumentsList를 반환한다.
AsyncFunctionBody : FunctionBody
  1. EvaluateAsyncFunctionBody of AsyncFunctionBody with arguments functionObject and argumentsList를 반환한다.
AsyncConciseBody : ExpressionBody
  1. EvaluateAsyncConciseBody of AsyncConciseBody with arguments functionObject and argumentsList를 반환한다.
Initializer : = AssignmentExpression
  1. Assert: argumentsList는 비어 있다.
  2. Assert: functionObject.[[ClassFieldInitializerName]]empty가 아니다.
  3. IsAnonymousFunctionDefinition(AssignmentExpression)가 true라면,
    1. value를 ? NamedEvaluation of Initializer with argument functionObject.[[ClassFieldInitializerName]]로 둔다.
  4. 그 외에는,
    1. rhs를 ? Evaluation of AssignmentExpression로 둔다.
    2. value를 ? GetValue(rhs)로 둔다.
  5. ReturnCompletion(value)를 반환한다.
참고

필드 이니셜라이저(Field initializer)는 함수 경계로 간주되지만, FunctionDeclarationInstantiation 호출은 관찰 가능한 효과가 없으므로 생략된다.

ClassStaticBlockBody : ClassStaticBlockStatementList
  1. Assert: argumentsList는 비어 있다.
  2. EvaluateClassStaticBlockBody of ClassStaticBlockBody with argument functionObject를 반환한다.

10.2.1.4 OrdinaryCallEvaluateBody ( F, argumentsList )

OrdinaryCallEvaluateBody 추상 연산은 F (ECMAScript 함수 객체)와 argumentsList (ECMAScript 언어 값의 리스트)를 인자로 받아, return completion 또는 throw completion을 반환한다. 호출 시 다음 단계를 수행한다:

  1. EvaluateBody of F.[[ECMAScriptCode]] with arguments FargumentsList를 반환한다.

10.2.2 [[Construct]] ( argumentsList, newTarget )

ECMAScript 함수 객체 F[[Construct]] 내부 메서드는 argumentsList (ECMAScript 언어 값의 리스트)와 newTarget (생성자)를 인자로 받고, 객체를 포함하는 정상 완료 또는 throw completion을 반환한다. 호출 시 다음 단계를 수행한다:

  1. callerContext실행 중인 실행 컨텍스트로 둔다.
  2. kindF.[[ConstructorKind]]로 둔다.
  3. kindbase이면,
    1. thisArgument를 ? OrdinaryCreateFromConstructor(newTarget, "%Object.prototype%")로 둔다.
  4. calleeContextPrepareForOrdinaryCall(F, newTarget)로 둔다.
  5. Assert: calleeContext가 현재 실행 중인 실행 컨텍스트임을 보장한다.
  6. kindbase이면,
    1. OrdinaryCallBindThis(F, calleeContext, thisArgument)를 수행한다.
    2. initializeResultCompletion(InitializeInstanceElements(thisArgument, F))로 둔다.
    3. initializeResultabrupt completion이면,
      1. calleeContext실행 컨텍스트 스택에서 제거하고, callerContext실행 중인 실행 컨텍스트로 복원한다.
      2. initializeResult를 반환한다.
  7. constructorEnvcalleeContext의 LexicalEnvironment로 둔다.
  8. resultCompletion(OrdinaryCallEvaluateBody(F, argumentsList))로 둔다.
  9. calleeContext실행 컨텍스트 스택에서 제거하고, callerContext실행 중인 실행 컨텍스트로 복원한다.
  10. resultthrow completion이면,
    1. result를 반환한다.
  11. Assert: resultreturn completion임을 보장한다.
  12. result.[[Value]]객체이면, result.[[Value]]를 반환한다.
  13. kindbase이면 thisArgument를 반환한다.
  14. result.[[Value]]undefined가 아니면 TypeError 예외를 던진다.
  15. thisBinding을 ? constructorEnv.GetThisBinding()으로 둔다.
  16. Assert: thisBinding객체임을 보장한다.
  17. thisBinding을 반환한다.

10.2.3 OrdinaryFunctionCreate ( functionPrototype, sourceText, ParameterList, Body, thisMode, env, privateEnv )

OrdinaryFunctionCreate 추상 연산은 functionPrototype (객체), sourceText (유니코드 코드 포인트 시퀀스), ParameterList (파스 노드), Body (파스 노드), thisMode (lexical-this 또는 non-lexical-this), env (환경 레코드), privateEnv (PrivateEnvironment 레코드 또는 null)를 인자로 받아, ECMAScript 함수 객체를 반환한다. 이 연산은 기본 [[Call]] 내부 메서드를 가지며 [[Construct]] 내부 메서드는 없는(단, MakeConstructor와 같은 연산으로 추가될 수 있음) 새 함수를 런타임에 생성하는 데 사용된다. sourceText는 생성할 함수의 문법 정의 소스 텍스트이다. 호출 시 다음 단계를 수행한다:

  1. internalSlotsList표 30에 나열된 내부 슬롯으로 둔다.
  2. FOrdinaryObjectCreate(functionPrototype, internalSlotsList)로 둔다.
  3. F.[[Call]]10.2.1에서 정의된 것으로 설정한다.
  4. F.[[SourceText]]sourceText로 설정한다.
  5. F.[[FormalParameters]]ParameterList로 설정한다.
  6. F.[[ECMAScriptCode]]Body로 설정한다.
  7. StrictIsStrict(Body)로 둔다.
  8. F.[[Strict]]Strict로 설정한다.
  9. thisModelexical-this이면 F.[[ThisMode]]lexical로 설정한다.
  10. 그 외에 Stricttrue이면 F.[[ThisMode]]strict로 설정한다.
  11. 그 외에는 F.[[ThisMode]]global로 설정한다.
  12. F.[[IsClassConstructor]]false로 설정한다.
  13. F.[[Environment]]env로 설정한다.
  14. F.[[PrivateEnvironment]]privateEnv로 설정한다.
  15. F.[[ScriptOrModule]]GetActiveScriptOrModule()로 설정한다.
  16. F.[[Realm]]현재 Realm Record로 설정한다.
  17. F.[[HomeObject]]undefined로 설정한다.
  18. F.[[Fields]]를 새로운 빈 List로 설정한다.
  19. F.[[PrivateMethods]]를 새로운 빈 List로 설정한다.
  20. F.[[ClassFieldInitializerName]]empty로 설정한다.
  21. lenExpectedArgumentCount of ParameterList로 둔다.
  22. SetFunctionLength(F, len)을 수행한다.
  23. F를 반환한다.

10.2.4 AddRestrictedFunctionProperties ( F, realm )

AddRestrictedFunctionProperties 추상 연산은 F (함수 객체)와 realm (Realm Record)를 인자로 받아 unused를 반환한다. 호출 시 다음 단계를 수행한다:

  1. Assert: realm.[[Intrinsics]].[[%ThrowTypeError%]]가 존재하며 초기화되어 있어야 한다.
  2. throwerrealm.[[Intrinsics]].[[%ThrowTypeError%]]로 둔다.
  3. DefinePropertyOrThrow(F, "caller", PropertyDescriptor { [[Get]]: thrower, [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: true })를 수행한다.
  4. DefinePropertyOrThrow(F, "arguments", PropertyDescriptor { [[Get]]: thrower, [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: true })를 수행한다.
  5. unused를 반환한다.

10.2.4.1 %ThrowTypeError% ( )

이 함수는 %ThrowTypeError% intrinsic 객체이다.

이것은 각 realm마다 하나씩 정의되는 익명 내장 함수 객체이다.

호출 시 다음 단계를 수행한다:

  1. TypeError 예외를 던진다.

이 함수의 [[Extensible]] 내부 슬롯의 값은 false이다.

이 함수의 "length" 프로퍼티의 속성은 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }이다.

이 함수의 "name" 프로퍼티의 속성은 { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }이다.

10.2.5 MakeConstructor ( F [ , writablePrototype [ , prototype ] ] )

추상 연산 MakeConstructor는 F (ECMAScript 함수 객체 또는 내장 함수 객체), 선택적 writablePrototype (불리언), prototype (객체)을 인자로 받아 unused를 반환한다. 이 연산은 F생성자로 변환한다. 호출 시 다음 단계를 수행한다:

  1. F가 ECMAScript 함수 객체라면,
    1. Assert: IsConstructor(F)가 false임을 보장한다.
    2. Assert: F는 확장 가능한 객체이며 "prototype" 자신의 프로퍼티를 갖지 않는다.
    3. F.[[Construct]]10.2.2에서 정의된 것으로 설정한다.
  2. 그 외의 경우,
    1. F.[[Construct]]10.3.2에서 정의된 것으로 설정한다.
  3. F.[[ConstructorKind]]base로 설정한다.
  4. writablePrototype이 생략되었으면 writablePrototypetrue로 설정한다.
  5. prototype이 생략되었으면,
    1. prototypeOrdinaryObjectCreate(%Object.prototype%)로 설정한다.
    2. DefinePropertyOrThrow(prototype, "constructor", PropertyDescriptor { [[Value]]: F, [[Writable]]: writablePrototype, [[Enumerable]]: false, [[Configurable]]: true })를 수행한다.
  6. DefinePropertyOrThrow(F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: writablePrototype, [[Enumerable]]: false, [[Configurable]]: false })를 수행한다.
  7. unused를 반환한다.

10.2.6 MakeClassConstructor ( F )

추상 연산 MakeClassConstructor는 F (ECMAScript 함수 객체)를 인자로 받아 unused를 반환한다. 호출 시 다음 단계를 수행한다:

  1. Assert: F.[[IsClassConstructor]]false임을 보장한다.
  2. F.[[IsClassConstructor]]true로 설정한다.
  3. unused를 반환한다.

10.2.7 MakeMethod ( F, homeObject )

추상 연산 MakeMethod는 F (ECMAScript 함수 객체)와 homeObject (객체)를 인자로 받아 unused를 반환한다. 이 연산은 F를 메서드로 설정한다. 호출 시 다음 단계를 수행한다:

  1. Assert: homeObject일반 객체임을 보장한다.
  2. F.[[HomeObject]]homeObject로 설정한다.
  3. unused를 반환한다.

10.2.8 DefineMethodProperty ( homeObject, key, closure, enumerable )

추상 연산 DefineMethodProperty는 homeObject (객체), key (프로퍼티 키 또는 Private Name), closure (함수 객체), enumerable (불리언)을 인자로 받고, 정상 완료로서 PrivateElement 또는 unused를 반환하거나, abrupt completion을 반환한다. 호출 시 다음 단계를 수행한다:

  1. Assert: homeObject는 일반적이고 확장 가능한 객체임을 보장한다.
  2. keyPrivate Name라면,
    1. PrivateElement { [[Key]]: key, [[Kind]]: method, [[Value]]: closure }를 반환한다.
  3. 그 외의 경우,
    1. desc를 PropertyDescriptor { [[Value]]: closure, [[Writable]]: true, [[Enumerable]]: enumerable, [[Configurable]]: true }로 둔다.
    2. DefinePropertyOrThrow(homeObject, key, desc)를 수행한다.
    3. 참고: DefinePropertyOrThrow는 클래스 정적 메서드의 key"prototype"일 때만 abrupt completion을 반환한다.
    4. unused를 반환한다.

10.2.9 SetFunctionName ( F, name [ , prefix ] )

추상 연산 SetFunctionName은 F (함수 객체), name (프로퍼티 키 또는 Private Name), 선택적 prefix (문자열)를 인자로 받아 unused를 반환한다. 이 연산은 F"name" 프로퍼티를 추가한다. 호출 시 다음 단계를 수행한다:

  1. Assert: F"name" 자신의 프로퍼티가 없는 확장 가능한 객체임을 보장한다.
  2. name심볼이면,
    1. descriptionname[[Description]] 값으로 둔다.
    2. descriptionundefined이면 name을 빈 문자열로 설정한다.
    3. 그 외에는 name문자열 연결"[", description, "]"을 합친 것으로 설정한다.
  3. 그 외에 namePrivate Name이면,
    1. namename.[[Description]]로 설정한다.
  4. F[[InitialName]] 내부 슬롯이 있으면,
    1. F.[[InitialName]]name으로 설정한다.
  5. prefix가 있으면,
    1. name문자열 연결prefix, 코드 유닛 0x0020(SPACE), name을 합친 것으로 설정한다.
    2. F[[InitialName]] 내부 슬롯이 있으면,
      1. 선택적으로 F.[[InitialName]]name으로 설정한다.
  6. DefinePropertyOrThrow(F, "name", PropertyDescriptor { [[Value]]: name, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true })를 수행한다.
  7. unused를 반환한다.

10.2.10 SetFunctionLength ( F, length )

추상 연산 SetFunctionLength는 F (함수 객체), length (0 이상의 정수 또는 +∞)를 인자로 받아 unused를 반환한다. 이 연산은 F"length" 프로퍼티를 추가한다. 호출 시 다음 단계를 수행한다:

  1. Assert: F"length" 자신의 프로퍼티가 없는 확장 가능한 객체임을 보장한다.
  2. DefinePropertyOrThrow(F, "length", PropertyDescriptor { [[Value]]: 𝔽(length), [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true })를 수행한다.
  3. unused를 반환한다.

10.2.11 FunctionDeclarationInstantiation ( func, argumentsList )

추상 연산 FunctionDeclarationInstantiation은 func (ECMAScript 함수 객체), argumentsList (ECMAScript 언어 값의 리스트)를 인자로 받아, unused를 포함하는 정상 완료 또는 throw completion을 반환한다. func실행 컨텍스트가 설정될 함수 객체이다.

참고 1

ECMAScript 함수의 평가를 위해 실행 컨텍스트가 설정되면 새로운 Function Environment Record가 생성되고, 각 형식 매개변수에 대한 바인딩이 해당 Environment Record에 인스턴스화된다. 함수 본문의 각 선언도 인스턴스화된다. 함수의 형식 매개변수에 기본값 이니셜라이저가 없으면 본문 선언은 매개변수와 같은 Environment Record에서 인스턴스화된다. 기본값 매개변수 이니셜라이저가 있으면, 본문 선언을 위한 두 번째 Environment Record가 생성된다. 형식 매개변수와 함수는 FunctionDeclarationInstantiation의 일부로 초기화된다. 그 외의 모든 바인딩은 함수 본문 평가 중에 초기화된다.

호출 시 다음 단계를 수행한다:

  1. calleeContext실행 중인 실행 컨텍스트로 둔다.
  2. codefunc.[[ECMAScriptCode]]로 둔다.
  3. strictfunc.[[Strict]]로 둔다.
  4. formalsfunc.[[FormalParameters]]로 둔다.
  5. parameterNamesBoundNames of formals로 둔다.
  6. parameterNames에 중복 항목이 있으면 hasDuplicatestrue로, 아니면 false로 둔다.
  7. simpleParameterListIsSimpleParameterList of formals로 둔다.
  8. hasParameterExpressionsContainsExpression of formals로 둔다.
  9. varNamesVarDeclaredNames of code로 둔다.
  10. varDeclarationsVarScopedDeclarations of code로 둔다.
  11. lexicalNamesLexicallyDeclaredNames of code로 둔다.
  12. functionNames를 새로운 빈 List로 둔다.
  13. functionsToInitialize를 새로운 빈 List로 둔다.
  14. varDeclarations의 각 요소 d에 대해, List의 역순으로, 다음을 수행한다:
    1. dVariableDeclaration, ForBinding, BindingIdentifier 중 어느 것도 아니면,
      1. Assert: dFunctionDeclaration, GeneratorDeclaration, AsyncFunctionDeclaration, AsyncGeneratorDeclaration 중 하나이다.
      2. fnBoundNames of d의 유일한 요소로 둔다.
      3. functionNamesfn이 포함되어 있지 않으면,
        1. fnfunctionNames의 첫 번째 요소로 삽입한다.
        2. 참고: 같은 이름의 함수 선언이 여러 번 있으면 마지막 선언이 사용된다.
        3. dfunctionsToInitialize의 첫 번째 요소로 삽입한다.
  15. argumentsObjectNeededtrue로 둔다.
  16. func.[[ThisMode]]lexical이면,
    1. 참고: 화살표 함수는 arguments 객체를 갖지 않는다.
    2. argumentsObjectNeededfalse로 설정한다.
  17. 그 외에 parameterNames"arguments"가 포함되어 있으면,
    1. argumentsObjectNeededfalse로 설정한다.
  18. 그 외에 hasParameterExpressionsfalse이면,
    1. functionNames"arguments"가 포함되어 있거나 lexicalNames"arguments"가 포함되어 있으면,
      1. argumentsObjectNeededfalse로 설정한다.
  19. stricttrue이거나 hasParameterExpressionsfalse이면,
    1. 참고: 엄격 모드 코드에서 eval 호출은 외부 바인딩을 볼 수 있는 새로운 바인딩을 만들 수 없으므로 매개변수에 대해 단일 Environment Record만 필요하다.
    2. envcalleeContext의 LexicalEnvironment로 둔다.
  20. 그 외의 경우,
    1. 참고: 형식 매개변수 목록에서 직접 eval 호출로 생성된 바인딩이 매개변수가 선언된 환경 외부에 있도록 별도의 Environment Record가 필요하다.
    2. calleeEnvcalleeContext의 LexicalEnvironment로 둔다.
    3. envNewDeclarativeEnvironment(calleeEnv)로 둔다.
    4. Assert: calleeContext의 VariableEnvironment와 calleeEnv는 같은 Environment Record이다.
    5. calleeContext의 LexicalEnvironment를 env로 설정한다.
  21. parameterNames의 각 문자열 paramName에 대해,
    1. alreadyDeclared를 ! env.HasBinding(paramName)으로 둔다.
    2. 참고: Early errors는 중복 매개변수 이름이 비엄격 함수에서만 발생하고, 이때 기본값이나 rest 파라미터가 없어야 함을 보장한다.
    3. alreadyDeclaredfalse이면,
      1. env.CreateMutableBinding(paramName, false)을 수행한다.
      2. hasDuplicatestrue이면,
        1. env.InitializeBinding(paramName, undefined)을 수행한다.
  22. argumentsObjectNeededtrue이면,
    1. stricttrue이거나 simpleParameterListfalse이면,
      1. aoCreateUnmappedArgumentsObject(argumentsList)로 둔다.
    2. 그 외의 경우,
      1. 참고: rest 파라미터, 기본값 이니셜라이저, 구조 분해 파라미터가 없는 비엄격 함수에만 mapped arguments 객체가 제공된다.
      2. aoCreateMappedArgumentsObject(func, formals, argumentsList, env)로 둔다.
    3. stricttrue이면,
      1. env.CreateImmutableBinding("arguments", false)을 수행한다.
      2. 참고: 엄격 모드 코드에서는 early errors가 이 바인딩에 할당을 시도하는 것을 방지하므로, mutability가 관찰되지 않는다.
    4. 그 외의 경우,
      1. env.CreateMutableBinding("arguments", false)을 수행한다.
    5. env.InitializeBinding("arguments", ao)를 수행한다.
    6. parameterBindingslist-concatenation of parameterNames 및 « "arguments" »로 둔다.
  23. 그 외의 경우,
    1. parameterBindingsparameterNames로 둔다.
  24. iteratorRecordCreateListIteratorRecord(argumentsList)로 둔다.
  25. hasDuplicatestrue이면,
    1. usedEnvundefined로 둔다.
  26. 그 외의 경우,
    1. usedEnvenv로 둔다.
  27. 참고: 다음 단계는 ReturnCompletion을 반환할 수 없다. 왜냐하면 식 위치에서 그런 완료가 발생할 수 있는 유일한 방법은 YieldExpression을 사용하는 것인데, 이는 15.5.115.6.1의 Early Error 규칙에 의해 파라미터 리스트에서 금지되어 있기 때문이다.
  28. IteratorBindingInitialization of formals with arguments iteratorRecordusedEnv를 수행한다.
  29. hasParameterExpressionsfalse이면,
    1. 참고: 매개변수와 top-level var를 위해 단일 Environment Record만 필요하다.
    2. instantiatedVarNamesparameterBindings의 복사본으로 둔다.
    3. varNames의 각 요소 n에 대해,
      1. instantiatedVarNamesn이 없으면,
        1. ninstantiatedVarNames에 추가한다.
        2. env.CreateMutableBinding(n, false)을 수행한다.
        3. env.InitializeBinding(n, undefined)을 수행한다.
    4. varEnvenv로 둔다.
  30. 그 외의 경우,
    1. 참고: 형식 매개변수 리스트 내 식에서 생성된 클로저가 함수 본문 내 선언을 볼 수 없도록 별도의 Environment Record가 필요하다.
    2. varEnvNewDeclarativeEnvironment(env)로 둔다.
    3. calleeContext의 VariableEnvironment를 varEnv로 설정한다.
    4. instantiatedVarNames를 새로운 빈 List로 둔다.
    5. varNames의 각 요소 n에 대해,
      1. instantiatedVarNamesn이 없으면,
        1. ninstantiatedVarNames에 추가한다.
        2. varEnv.CreateMutableBinding(n, false)을 수행한다.
        3. parameterBindingsn이 없거나 functionNamesn이 있으면,
          1. initialValueundefined로 둔다.
        4. 그 외의 경우,
          1. initialValue를 ! env.GetBindingValue(n, false)로 둔다.
        5. varEnv.InitializeBinding(n, initialValue)를 수행한다.
        6. 참고: 형식 매개변수와 같은 이름의 var는 해당 초기화된 파라미터와 같은 값을 처음 가진다.
  31. 참고: 부록 B.3.2.1은 이 위치에 추가 단계를 둔다.
  32. strictfalse이면,
    1. lexEnvNewDeclarativeEnvironment(varEnv)로 둔다.
    2. 참고: 비엄격 함수는 top-level lexical 선언을 위해 별도의 Environment Record를 사용하며, 이는 직접 eval이 eval 코드로 도입한 var 범위 선언이 기존 top-level lexical 선언과 충돌하는지 판단할 수 있도록 한다. 엄격 함수에는 필요하지 않다. 엄격 직접 eval은 항상 모든 선언을 새로운 Environment Record에 위치시킨다.
  33. 그 외의 경우,
    1. lexEnvvarEnv로 둔다.
  34. calleeContext의 LexicalEnvironment를 lexEnv로 설정한다.
  35. lexDeclarationsLexicallyScopedDeclarations of code로 둔다.
  36. lexDeclarations의 각 요소 d에 대해,
    1. 참고: lexical 선언된 이름은 함수/제너레이터 선언, 형식 매개변수, var 이름과 같을 수 없다. lexical 선언된 이름은 여기서 인스턴스화만 되고 초기화되지 않는다.
    2. BoundNames of d의 각 요소 dn에 대해,
      1. IsConstantDeclaration of dtrue이면,
        1. lexEnv.CreateImmutableBinding(dn, true)를 수행한다.
      2. 그 외의 경우,
        1. lexEnv.CreateMutableBinding(dn, false)를 수행한다.
  37. privateEnvcalleeContext의 PrivateEnvironment로 둔다.
  38. functionsToInitialize의 각 파스 노드 f에 대해,
    1. fnBoundNames of f의 유일한 요소로 둔다.
    2. foInstantiateFunctionObject of f with arguments lexEnvprivateEnv로 둔다.
    3. varEnv.SetMutableBinding(fn, fo, false)를 수행한다.
  39. unused를 반환한다.
참고 2

B.3.2 는 ECMAScript 2015 이전의 웹 브라우저 구현과의 하위 호환성을 위해 위 알고리즘에 대한 확장을 제공한다.

10.3 내장 함수 객체

내장 함수 객체일반 객체이며, 일반 객체에 대한 10.1의 요구사항을 반드시 만족해야 합니다.

모든 일반 객체에 요구되는 내부 슬롯(자세한 내용은 10.1 참고) 외에, 내장 함수 객체는 다음 내부 슬롯도 반드시 가져야 합니다:

  • [[Realm]]: 함수가 생성된 realm을 나타내는 Realm Record.
  • [[InitialName]]: 함수의 초기 이름을 나타내는 문자열. 20.2.3.5에서 사용됩니다.

내장 함수 객체[[Prototype]] 내부 슬롯의 초기값은 별도의 명시가 없는 한 %Function.prototype%입니다.

내장 함수 객체10.3.1에 정의된 [[Call]] 내부 메서드를 반드시 가져야 합니다.

내장 함수 객체는 “생성자”로 기술되어 있거나, 이 명세의 어떤 알고리즘이 명시적으로 [[Construct]] 내부 메서드를 설정한 경우에만 [[Construct]] 내부 메서드를 가집니다. 이러한 [[Construct]] 내부 메서드는 반드시 10.3.2에 정의된 내용을 따라야 합니다.

구현체는 이 명세에 정의되지 않은 추가적인 내장 함수 객체를 제공할 수 있습니다.

10.3.1 [[Call]] ( thisArgument, argumentsList )

내장 함수 객체 F[[Call]] 내부 메서드는 thisArgument (ECMAScript 언어 값), argumentsList (ECMAScript 언어 값의 리스트)를 인자로 받아, ECMAScript 언어 값를 포함하는 정상 완료 또는 throw completion을 반환한다. 호출 시 다음 단계를 수행한다:

  1. BuiltinCallOrConstruct(F, thisArgument, argumentsList, undefined)를 반환한다.

10.3.2 [[Construct]] ( argumentsList, newTarget )

내장 함수 객체 F[[Construct]] 내부 메서드(존재하는 경우)는 argumentsList (ECMAScript 언어 값의 리스트), newTarget (생성자)를 인자로 받아, 객체를 포함하는 정상 완료 또는 throw completion을 반환한다. 호출 시 다음 단계를 수행한다:

  1. result를 ? BuiltinCallOrConstruct(F, uninitialized, argumentsList, newTarget)로 둔다.
  2. Assert: result객체임을 보장한다.
  3. result를 반환한다.

10.3.3 BuiltinCallOrConstruct ( F, thisArgument, argumentsList, newTarget )

BuiltinCallOrConstruct 추상 연산은 F (내장 함수 객체), thisArgument (ECMAScript 언어 값 또는 uninitialized), argumentsList (ECMAScript 언어 값의 리스트), newTarget (생성자 또는 undefined)를 인자로 받아, ECMAScript 언어 값를 포함하는 정상 완료 또는 throw completion을 반환한다. 호출 시 다음 단계를 수행한다:

  1. callerContext실행 중인 실행 컨텍스트로 둔다.
  2. callerContext가 이미 일시정지(suspended) 상태가 아니면, callerContext를 일시정지시킨다.
  3. calleeContext를 새로운 실행 컨텍스트로 둔다.
  4. calleeContext의 Function을 F로 설정한다.
  5. calleeRealmF.[[Realm]]로 둔다.
  6. calleeContextRealmcalleeRealm으로 설정한다.
  7. calleeContext의 ScriptOrModule을 null로 설정한다.
  8. calleeContext의 구현체 정의 초기화(implementation-defined initialization)를 수행한다.
  9. calleeContext실행 컨텍스트 스택에 푸시한다; calleeContext는 이제 실행 중인 실행 컨텍스트이다.
  10. resultCompletion Record로, F를 이 명세에 정의된 대로 평가한 결과로 둔다. thisArgumentuninitialized이면 this 값은 미초기화 상태이고, 아니면 thisArgumentthis 값을 제공한다. argumentsList는 명명된 파라미터를 제공하며, newTarget은 NewTarget 값을 제공한다.
  11. 참고: F가 이 문서에서 정의된 경우, “the specification of F”는 알고리즘 단계 또는 그 외 수단으로 명세된 동작이다.
  12. calleeContext실행 컨텍스트 스택에서 제거하고, callerContext실행 중인 실행 컨텍스트로 복원한다.
  13. result를 반환한다.
참고

calleeContext실행 컨텍스트 스택에서 제거될 때, 접근 가능한 Generator에 의해 나중에 재개(resume)될 수 있도록 일시정지(suspend) 상태라면 파괴되어서는 안 됩니다.

10.3.4 CreateBuiltinFunction ( behaviour, length, name, additionalInternalSlotsList [ , realm [ , prototype [ , prefix ] ] ] )

CreateBuiltinFunction 추상 연산은 behaviour (Abstract Closure, 알고리즘 단계 집합, 또는 명세 내에서 함수 동작을 정의한 기타 수단), length (0 이상의 정수 또는 +∞), name (프로퍼티 키 또는 Private Name), additionalInternalSlotsList (내부 슬롯 이름 리스트), 그리고 선택적 realm (Realm Record), prototype (객체 또는 null), prefix (문자열)을 인자로 받아 내장 함수 객체를 반환한다. additionalInternalSlotsList에는 객체의 일부로 정의되어야 하는 추가 내부 슬롯 이름이 포함된다. 이 연산은 내장 함수 객체를 생성한다. 호출 시 다음 단계를 수행한다:

  1. realm이 없으면 realm현재 Realm Record로 설정한다.
  2. prototype이 없으면 prototyperealm.[[Intrinsics]].[[%Function.prototype%]]로 설정한다.
  3. internalSlotsList를, 생성할 내장 함수 객체에 대해 10.3이 요구하는 모든 내부 슬롯의 이름을 포함하는 List로 둔다.
  4. internalSlotsList 끝에 additionalInternalSlotsList의 모든 요소를 추가한다.
  5. func를, 호출 시 behaviour에서 명시된 대로 해당 인자를 파라미터 값으로 사용하여 행동하는 새로운 내장 함수 객체로 둔다. 새 함수 객체internalSlotsList의 이름을 가진 내부 슬롯들과, [[InitialName]] 내부 슬롯을 가진다.
  6. func.[[Prototype]]prototype으로 설정한다.
  7. func.[[Extensible]]true로 설정한다.
  8. func.[[Realm]]realm으로 설정한다.
  9. func.[[InitialName]]null로 설정한다.
  10. SetFunctionLength(func, length)를 수행한다.
  11. prefix가 없으면,
    1. SetFunctionName(func, name)을 수행한다.
  12. 그 외의 경우,
    1. SetFunctionName(func, name, prefix)를 수행한다.
  13. func를 반환한다.

이 명세에 정의된 모든 내장 함수는 CreateBuiltinFunction 추상 연산을 호출하여 생성된다.

10.4 내장 익조틱(Exotic) 객체의 내부 메서드와 슬롯

이 명세는 여러 종류의 내장 익조틱 객체를 정의합니다. 이러한 객체들은 몇몇 특정 상황을 제외하면 일반적으로 일반 객체와 비슷하게 동작합니다. 아래의 익조틱 객체들은 별도로 명시된 경우를 제외하고는 일반 객체의 내부 메서드를 사용합니다:

10.4.1 바운드 함수 익조틱 객체

바운드 함수 익조틱 객체는 또 다른 함수 객체를 감싸는 익조틱 객체입니다. 바운드 함수 익조틱 객체는 호출 가능하며([[Call]] 내부 메서드를 가지고 있을 수 있고, [[Construct]] 내부 메서드도 가질 수 있습니다), 이를 호출하면 일반적으로 감싸고 있는 함수가 호출됩니다.

객체가 [[Call]] 및 (해당되는 경우) [[Construct]] 내부 메서드가 아래 구현을 따르고, 그 외의 필수 내부 메서드는 10.1의 정의를 따른다면, 그 객체는 바운드 함수 익조틱 객체입니다. 이러한 메서드는 BoundFunctionCreate에서 설치됩니다.

바운드 함수 익조틱 객체표 30에 나열된 ECMAScript 함수 객체의 내부 슬롯을 가지지 않습니다. 대신, [[Prototype]][[Extensible]]와 더불어 표 31에 나열된 내부 슬롯을 가집니다.

표 31: 바운드 함수 익조틱 객체의 내부 슬롯
내부 슬롯 타입 설명
[[BoundTargetFunction]] 호출 가능한 객체 감싸고 있는 함수 객체.
[[BoundThis]] ECMAScript 언어 값 감싸고 있는 함수를 호출할 때 항상 this 값으로 전달되는 값입니다.
[[BoundArguments]] 리스트 (ECMAScript 언어 값의 리스트) 감싸고 있는 함수를 호출할 때 항상 첫 번째 인수로 전달되는 값들의 리스트입니다.

10.4.1.1 [[Call]] ( thisArgument, argumentsList )

바운드 함수 익조틱 객체 F[[Call]] 내부 메서드는 thisArgument (ECMAScript 언어 값), argumentsList (ECMAScript 언어 값 리스트)를 인자로 받아, ECMAScript 언어 값를 포함하는 정상 완료 또는 throw completion을 반환한다. 호출 시 다음 단계를 수행한다:

  1. targetF.[[BoundTargetFunction]]으로 둔다.
  2. boundThisF.[[BoundThis]]로 둔다.
  3. boundArgsF.[[BoundArguments]]로 둔다.
  4. args리스트 연결(boundArgs, argumentsList)로 둔다.
  5. Call(target, boundThis, args)를 반환한다.

10.4.1.2 [[Construct]] ( argumentsList, newTarget )

바운드 함수 익조틱 객체 F[[Construct]] 내부 메서드는 argumentsList (ECMAScript 언어 값 리스트), newTarget (생성자)를 인자로 받아, 객체를 포함하는 정상 완료 또는 throw completion을 반환한다. 호출 시 다음 단계를 수행한다:

  1. targetF.[[BoundTargetFunction]]으로 둔다.
  2. Assert: IsConstructor(target)가 true임을 보장한다.
  3. boundArgsF.[[BoundArguments]]로 둔다.
  4. args리스트 연결(boundArgs, argumentsList)로 둔다.
  5. SameValue(F, newTarget)가 true이면, newTargettarget으로 설정한다.
  6. Construct(target, args, newTarget)를 반환한다.

10.4.1.3 BoundFunctionCreate ( targetFunction, boundThis, boundArgs )

BoundFunctionCreate 추상 연산은 targetFunction (함수 객체), boundThis (ECMAScript 언어 값), boundArgs (ECMAScript 언어 값 리스트)를 인자로 받아, 함수 객체를 포함하는 정상 완료 또는 throw completion을 반환한다. 이 연산은 새로운 바운드 함수 익조틱 객체의 생성을 명세하는 데 사용된다. 호출 시 다음 단계를 수행한다:

  1. proto를 ? targetFunction.[[GetPrototypeOf]]()로 둔다.
  2. internalSlotsList리스트 연결로 « [[Prototype]], [[Extensible]] »와 표 31에 나열된 내부 슬롯들을 합친 것으로 둔다.
  3. objMakeBasicObject(internalSlotsList)로 둔다.
  4. obj.[[Prototype]]proto로 설정한다.
  5. obj.[[Call]]10.4.1.1에서 설명한 대로 설정한다.
  6. IsConstructor(targetFunction) 가 true이면,
    1. obj.[[Construct]]10.4.1.2에서 설명한 대로 설정한다.
  7. obj.[[BoundTargetFunction]]targetFunction으로 설정한다.
  8. obj.[[BoundThis]]boundThis로 설정한다.
  9. obj.[[BoundArguments]]boundArgs로 설정한다.
  10. obj를 반환한다.

10.4.2 배열 익조틱 객체

배열(Array)은 익조틱 객체로, 배열 인덱스 프로퍼티 키에 대해 특별한 처리를 합니다(자세한 내용은 6.1.7 참고). 프로퍼티 이름배열 인덱스인 프로퍼티는 요소(element)라고도 부릅니다. 모든 배열은 항상 0 이상의 정수(Number) 값을 가지며, 그 수학적 값이 232 미만인, 변경 불가능(non-configurable)한 "length" 프로퍼티를 가집니다. "length" 프로퍼티의 값은 그 이름이 배열 인덱스인 모든 자신의 프로퍼티 이름보다 숫자적으로 큽니다. 배열의 자신의 프로퍼티가 생성되거나 변경될 때마다 이 불변식(invariant)을 유지하기 위해 다른 프로퍼티들도 필요에 따라 조정됩니다. 구체적으로, 이름이 배열 인덱스인 자신의 프로퍼티가 추가되면, 필요하다면 "length" 프로퍼티의 값을 해당 배열 인덱스의 수치값 + 1로 변경합니다. 그리고 "length"의 값이 변경될 때마다, 그 값 이상인 모든 배열 인덱스 이름을 가진 자신의 프로퍼티를 삭제합니다. 이 제약은 배열의 자신의 프로퍼티에만 적용되며, "length"배열 인덱스 프로퍼티가 프로토타입에서 상속된 경우에는 영향을 미치지 않습니다.

객체의 [[DefineOwnProperty]] 내부 메서드가 아래 구현을 따르고, 그 외의 필수 내부 메서드가 10.1의 정의를 따른다면, 그 객체는 배열 익조틱 객체(또는 간단히 배열)입니다. 이러한 메서드는 ArrayCreate에서 설치됩니다.

10.4.2.1 [[DefineOwnProperty]] ( P, Desc )

배열 익조틱 객체 A[[DefineOwnProperty]] 내부 메서드는 P (프로퍼티 키), Desc (프로퍼티 디스크립터)를 인자로 받고, 불리언을 포함하는 정상 완료 또는 throw completion을 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. P"length"이면,
    1. ArraySetLength(A, Desc)를 반환합니다.
  2. 그 외에 P배열 인덱스이면,
    1. lengthDescOrdinaryGetOwnProperty(A, "length")로 둔다.
    2. Assert: lengthDescundefined가 아님을 보장합니다.
    3. Assert: IsDataDescriptor(lengthDesc)가 true임을 보장합니다.
    4. Assert: lengthDesc.[[Configurable]]false임을 보장합니다.
    5. lengthlengthDesc.[[Value]]로 둔다.
    6. Assert: length가 0 이상의 정수(Number)임을 보장합니다.
    7. index를 ! ToUint32(P)로 둡니다.
    8. indexlength이고 lengthDesc.[[Writable]]false이면, false를 반환합니다.
    9. succeeded를 ! OrdinaryDefineOwnProperty(A, P, Desc)로 둡니다.
    10. succeededfalse이면, false를 반환합니다.
    11. indexlength이면,
      1. lengthDesc.[[Value]]index + 1𝔽로 설정합니다.
      2. succeeded를 ! OrdinaryDefineOwnProperty(A, "length", lengthDesc)로 둡니다.
      3. Assert: succeededtrue임을 보장합니다.
    12. true를 반환합니다.
  3. OrdinaryDefineOwnProperty(A, P, Desc)를 반환합니다.

10.4.2.2 ArrayCreate ( length [ , proto ] )

ArrayCreate 추상 연산은 length (0 이상의 정수), 선택적 proto (객체)를 인자로 받아, 배열 익조틱 객체를 포함하는 정상 완료 또는 throw completion을 반환합니다. 이는 새로운 배열 생성 시 사용됩니다. 호출 시 다음 단계를 수행합니다:

  1. length > 232 - 1이면 RangeError 예외를 던집니다.
  2. proto가 없으면 proto%Array.prototype%로 설정합니다.
  3. AMakeBasicObject[[Prototype]], [[Extensible]] »)로 둡니다.
  4. A.[[Prototype]]proto로 설정합니다.
  5. A.[[DefineOwnProperty]]10.4.2.1에 명시된 대로 설정합니다.
  6. OrdinaryDefineOwnProperty(A, "length", PropertyDescriptor { [[Value]]: 𝔽(length), [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false })를 수행합니다.
  7. A를 반환합니다.

10.4.2.3 ArraySpeciesCreate ( originalArray, length )

ArraySpeciesCreate 추상 연산은 originalArray (객체), length (0 이상의 정수)를 인자로 받아, 객체를 포함하는 정상 완료 또는 throw completion을 반환합니다. 이는 originalArray에서 파생된 생성자 함수를 사용해 새로운 배열 또는 유사 객체를 생성할 때 사용됩니다. 여기서 생성자 함수가 반드시 Array를 반환할 필요는 없습니다. 호출 시 다음 단계를 수행합니다:

  1. isArray를 ? IsArray(originalArray)로 둡니다.
  2. isArrayfalse이면 ? ArrayCreate(length)를 반환합니다.
  3. C를 ? Get(originalArray, "constructor")로 둡니다.
  4. IsConstructor(C)가 true이면,
    1. thisRealm현재 Realm Record로 둡니다.
    2. realmC를 ? GetFunctionRealm(C)로 둡니다.
    3. thisRealmrealmC가 동일한 Realm Record가 아니면,
      1. SameValue(C, realmC.[[Intrinsics]].[[%Array%]])가 true이면 Cundefined로 둡니다.
  5. C객체이면,
    1. C를 ? Get(C, %Symbol.species%)로 둡니다.
    2. Cnull이면 Cundefined로 둡니다.
  6. Cundefined이면 ? ArrayCreate(length)를 반환합니다.
  7. IsConstructor(C)가 false이면 TypeError 예외를 던집니다.
  8. Construct(C, « 𝔽(length) »)를 반환합니다.
참고

originalArrayrealm실행 중인 실행 컨텍스트realm와 다를 때, 표준 내장 Array 생성자로 생성된 경우에는 실행 중인 실행 컨텍스트realm에서 새로운 배열이 생성됩니다. 이는 ArraySpeciesCreate를 사용하는 Array.prototype 메서드가 역사적으로 웹 브라우저에서 이런 동작을 보였던 것과의 호환성을 유지하기 위한 것입니다.

10.4.2.4 ArraySetLength ( A, Desc )

ArraySetLength 추상 연산은 A (배열), Desc (프로퍼티 디스크립터)를 인자로 받아, 불리언을 포함하는 정상 완료 또는 throw completion을 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. Desc[[Value]] 필드가 없으면,
    1. OrdinaryDefineOwnProperty(A, "length", Desc)를 반환합니다.
  2. newLenDescDesc의 복사본으로 둔다.
  3. newLen를 ? ToUint32(Desc.[[Value]])로 둔다.
  4. numberLen를 ? ToNumber(Desc.[[Value]])로 둔다.
  5. SameValueZero(newLen, numberLen)이 false이면 RangeError 예외를 던집니다.
  6. newLenDesc.[[Value]]newLen로 설정합니다.
  7. oldLenDescOrdinaryGetOwnProperty(A, "length")로 둡니다.
  8. Assert: oldLenDescundefined가 아님을 보장합니다.
  9. Assert: IsDataDescriptor(oldLenDesc)가 true임을 보장합니다.
  10. Assert: oldLenDesc.[[Configurable]]false임을 보장합니다.
  11. oldLenoldLenDesc.[[Value]]로 둡니다.
  12. newLenoldLen이면,
    1. OrdinaryDefineOwnProperty(A, "length", newLenDesc)를 반환합니다.
  13. oldLenDesc.[[Writable]]false이면, false를 반환합니다.
  14. newLenDesc[[Writable]] 필드가 없거나 newLenDesc.[[Writable]]true이면,
    1. newWritabletrue로 둡니다.
  15. 그 외의 경우,
    1. 참고: [[Writable]] 속성을 false로 설정하는 것은 요소 삭제에 실패하는 경우를 대비해 미룹니다.
    2. newWritablefalse로 둡니다.
    3. newLenDesc.[[Writable]]true로 설정합니다.
  16. succeeded를 ! OrdinaryDefineOwnProperty(A, "length", newLenDesc)로 둡니다.
  17. succeededfalse이면, false를 반환합니다.
  18. 자신의 프로퍼티 키 P 중, P배열 인덱스이고, ! ToUint32(P) ≥ newLen인 모든 P에 대해, 내림차순 숫자 인덱스 순으로,
    1. deleteSucceeded를 ! A.[[Delete]](P)로 둡니다.
    2. deleteSucceededfalse이면,
      1. newLenDesc.[[Value]]를 ! ToUint32(P) + 1𝔽로 설정합니다.
      2. newWritablefalse이면, newLenDesc.[[Writable]]false로 설정합니다.
      3. OrdinaryDefineOwnProperty(A, "length", newLenDesc)를 수행합니다.
      4. false를 반환합니다.
  19. newWritablefalse이면,
    1. succeeded를 ! OrdinaryDefineOwnProperty(A, "length", PropertyDescriptor { [[Writable]]: false })로 둡니다.
    2. Assert: succeededtrue임을 보장합니다.
  20. true를 반환합니다.
참고

34 단계에서 Desc.[[Value]]가 객체인 경우 valueOf 메서드가 두 번 호출됩니다. 이는 2판(Edition 2) 명세에서 이 효과를 명시한 이후로 유지되고 있는 레거시 동작입니다.

10.4.3 문자열 익조틱 객체

String 객체는 문자열 값을 캡슐화하고, 해당 문자열 값의 각 코드 유닛 요소에 대응하는 가상 정수 인덱스 데이터 프로퍼티를 노출하는 익조틱 객체입니다. 문자열 익조틱 객체는 항상 캡슐화된 문자열 값의 길이를 값으로 갖는 "length"라는 이름의 데이터 프로퍼티를 가집니다. 코드 유닛 데이터 프로퍼티"length" 프로퍼티 모두 쓰기 불가 및 재정의 불가(non-configurable)입니다.

객체의 [[GetOwnProperty]], [[DefineOwnProperty]], [[OwnPropertyKeys]] 내부 메서드가 아래 구현을 따르고, 그 외의 필수 내부 메서드는 10.1의 정의를 따른다면, 그 객체는 문자열 익조틱 객체(혹은 간단히 String 객체)입니다. 이 메서드들은 StringCreate에서 설치됩니다.

문자열 익조틱 객체일반 객체와 동일한 내부 슬롯을 가지며, 추가로 [[StringData]] 내부 슬롯을 가집니다.

10.4.3.1 [[GetOwnProperty]] ( P )

문자열 익조틱 객체 S[[GetOwnProperty]] 내부 메서드는 P (프로퍼티 키)를 인자로 받아, 프로퍼티 디스크립터 또는 undefined를 포함하는 정상 완료를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. descOrdinaryGetOwnProperty(S, P)로 둡니다.
  2. descundefined가 아니면 desc를 반환합니다.
  3. StringGetOwnProperty(S, P)를 반환합니다.

10.4.3.2 [[DefineOwnProperty]] ( P, Desc )

문자열 익조틱 객체 S[[DefineOwnProperty]] 내부 메서드는 P (프로퍼티 키), Desc (프로퍼티 디스크립터)를 인자로 받아, 불리언을 포함하는 정상 완료를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. stringDescStringGetOwnProperty(S, P)로 둡니다.
  2. stringDescundefined가 아니면,
    1. extensibleS.[[Extensible]]로 둔다.
    2. IsCompatiblePropertyDescriptor(extensible, Desc, stringDesc)를 반환한다.
  3. OrdinaryDefineOwnProperty(S, P, Desc)를 반환한다.

10.4.3.3 [[OwnPropertyKeys]] ( )

문자열 익조틱 객체 O[[OwnPropertyKeys]] 내부 메서드는 인자를 받지 않으며, 프로퍼티 키리스트를 포함하는 정상 완료를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. keys를 새로운 빈 리스트로 둔다.
  2. strO.[[StringData]]로 둔다.
  3. Assert: str문자열임을 보장한다.
  4. lenstr의 길이로 둔다.
  5. 0 ≤ i < len인 모든 정수 i에 대해 오름차순으로,
    1. ToString(𝔽(i))를 keys에 추가한다.
  6. 자신의 프로퍼티 키 P 중, P배열 인덱스이고, ! ToIntegerOrInfinity(P) ≥ len인 모든 P에 대해 오름차순 숫자 인덱스 순서대로,
    1. Pkeys에 추가한다.
  7. 자신의 프로퍼티 키 P 중, P문자열이고 배열 인덱스가 아닌 모든 P에 대해 프로퍼티 생성 시점의 오름차순 순서대로,
    1. Pkeys에 추가한다.
  8. 자신의 프로퍼티 키 P 중, P심볼인 모든 P에 대해 프로퍼티 생성 시점의 오름차순 순서대로,
    1. Pkeys에 추가한다.
  9. keys를 반환한다.

10.4.3.4 StringCreate ( value, prototype )

StringCreate 추상 연산은 value (문자열), prototype (객체)를 인자로 받아 문자열 익조틱 객체를 반환한다. 이는 새로운 문자열 익조틱 객체의 생성을 명세하는 데 사용된다. 호출 시 다음 단계를 수행한다:

  1. SMakeBasicObject[[Prototype]], [[Extensible]], [[StringData]] »)로 둔다.
  2. S.[[Prototype]]prototype으로 설정한다.
  3. S.[[StringData]]value로 설정한다.
  4. S.[[GetOwnProperty]]10.4.3.1에 명시된 대로 설정한다.
  5. S.[[DefineOwnProperty]]10.4.3.2에 명시된 대로 설정한다.
  6. S.[[OwnPropertyKeys]]10.4.3.3에 명시된 대로 설정한다.
  7. lengthvalue의 길이로 둔다.
  8. DefinePropertyOrThrow(S, "length", PropertyDescriptor { [[Value]]: 𝔽(length), [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false })를 수행한다.
  9. S를 반환한다.

10.4.3.5 StringGetOwnProperty ( S, P )

StringGetOwnProperty 추상 연산은 S ([[StringData]] 내부 슬롯이 있는 객체), P (프로퍼티 키)를 인자로 받아, 프로퍼티 디스크립터 또는 undefined를 반환한다. 호출 시 다음 단계를 수행한다:

  1. P문자열이 아니면 undefined를 반환한다.
  2. indexCanonicalNumericIndexString(P)로 둔다.
  3. index정수(Number)가 아니면 undefined를 반환한다.
  4. index-0𝔽이거나 index < -0𝔽이면 undefined를 반환한다.
  5. strS.[[StringData]]로 둔다.
  6. Assert: str문자열임을 보장한다.
  7. lenstr의 길이로 둔다.
  8. (index) ≥ len이면 undefined를 반환한다.
  9. resultStrsubstring(str, (index), (index) + 1)로 둔다.
  10. PropertyDescriptor { [[Value]]: resultStr, [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: false }를 반환한다.

10.4.4 Arguments 익조틱 객체

대부분의 ECMAScript 함수는 arguments 객체를 코드에서 사용할 수 있도록 제공합니다. 함수 정의의 특성에 따라, arguments 객체는 일반 객체이거나 arguments 익조틱 객체입니다. arguments 익조틱 객체익조틱 객체로, 배열 인덱스 프로퍼티가 관련 ECMAScript 함수의 호출 시 형식 매개변수 바인딩과 매핑됩니다.

객체의 내부 메서드가 아래 구현을 따르고, 여기 명시되지 않은 메서드는 10.1의 정의를 따른다면, 그 객체는 arguments 익조틱 객체입니다. 이러한 메서드는 CreateMappedArgumentsObject에서 설치됩니다.

참고 1

CreateUnmappedArgumentsObject 는 이 절에 포함되어 있지만, arguments 익조틱 객체가 아니라 일반 객체를 생성합니다.

Arguments 익조틱 객체일반 객체와 동일한 내부 슬롯을 가지고 있습니다. 또한 [[ParameterMap]] 내부 슬롯을 가집니다. 일반 arguments 객체도 [[ParameterMap]] 내부 슬롯을 가지지만, 그 값은 항상 undefined입니다. 일반 arguments 객체에서 [[ParameterMap]] 내부 슬롯은 Object.prototype.toString (20.1.3.6)에서 해당 객체임을 식별하는 데만 사용됩니다.

참고 2

arguments 익조틱 객체정수 인덱스 데이터 프로퍼티 중 이름이 해당 함수 객체의 형식 매개변수 개수보다 작은 것은 처음에 함수 실행 컨텍스트의 인수 바인딩과 값을 공유합니다. 즉, 프로퍼티를 변경하면 인수 바인딩의 값도 바뀌고 그 반대도 마찬가지입니다. 이 대응은 해당 프로퍼티를 삭제 후 재정의하거나 접근자 프로퍼티로 바꾸면 끊어집니다. arguments 객체가 일반 객체라면, 프로퍼티의 값은 함수에 전달된 인수의 복사본일 뿐이며, 프로퍼티 값과 형식 매개변수 값 사이에 동적 연결은 없습니다.

참고 3

ParameterMap 객체와 그 프로퍼티 값은 arguments 객체와 인수 바인딩의 대응을 명세하기 위한 장치로 사용됩니다. ParameterMap 객체와 그 프로퍼티 값 객체는 ECMAScript 코드에서 직접 관찰할 수 없습니다. 명세된 의미론을 구현하기 위해, ECMAScript 구현체는 실제로 이러한 객체를 생성하거나 사용할 필요가 없습니다.

참고 4

일반 arguments 객체는 접근 시 TypeError 예외를 던지는 "callee"라는 이름의 변경 불가 접근자 프로퍼티를 정의합니다. arguments 익조틱 객체"callee" 프로퍼티에 대해 좀 더 구체적인 의미를 가지며, 이는 일부 비엄격 함수에 대해서만 생성됩니다. 일반 variant에서 이 프로퍼티를 정의하는 것은, ECMAScript 구현체가 이와 다른 방법으로 프로퍼티를 정의하지 않도록 보장하기 위함입니다.

참고 5

ECMAScript의 arguments 익조틱 객체 구현체는 역사적으로 "caller"라는 접근자 프로퍼티를 포함하는 경우가 있었습니다. ECMAScript 2017 이전에는 이 명세서에 일반 arguments 객체에 대해 예외를 던지는 "caller" 프로퍼티 정의가 포함되어 있었습니다. 현재는 구현체가 더 이상 이 확장을 포함하지 않으므로, ECMAScript 2017에서 이 요구사항을 삭제하였습니다.

10.4.4.1 [[GetOwnProperty]] ( P )

arguments 익조틱 객체 args[[GetOwnProperty]] 내부 메서드는 P (프로퍼티 키)를 인자로 받아, 프로퍼티 디스크립터 또는 undefined를 포함하는 정상 완료를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. descOrdinaryGetOwnProperty(args, P)로 둔다.
  2. descundefined이면 undefined를 반환한다.
  3. mapargs.[[ParameterMap]]로 둔다.
  4. isMapped를 ! HasOwnProperty(map, P)로 둔다.
  5. isMappedtrue이면,
    1. desc.[[Value]]를 ! Get(map, P)로 설정한다.
  6. desc를 반환한다.

10.4.4.2 [[DefineOwnProperty]] ( P, Desc )

arguments 익조틱 객체 args[[DefineOwnProperty]] 내부 메서드는 P (프로퍼티 키), Desc (프로퍼티 디스크립터)를 인자로 받아 불리언을 포함하는 정상 완료를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. mapargs.[[ParameterMap]]로 둔다.
  2. isMapped를 ! HasOwnProperty(map, P)로 둔다.
  3. newArgDescDesc로 둔다.
  4. isMappedtrue이고 IsDataDescriptor(Desc) 가 true이면,
    1. Desc[[Value]] 필드가 없고, Desc[[Writable]] 필드가 있으면서 Desc.[[Writable]]false이면,
      1. newArgDescDesc의 복사본으로 둔다.
      2. newArgDesc.[[Value]]를 ! Get(map, P)로 설정한다.
  5. allowed를 ! OrdinaryDefineOwnProperty(args, P, newArgDesc)로 둔다.
  6. allowedfalse이면 false를 반환한다.
  7. isMappedtrue이면,
    1. IsAccessorDescriptor(Desc) 가 true이면,
      1. map.[[Delete]](P)를 수행한다.
    2. 그 외의 경우,
      1. Desc[[Value]] 필드가 있으면,
        1. Assert: 아래 Set은 반드시 성공한다. arguments 객체에 의해 매핑되는 형식 매개변수는 항상 writable이다.
        2. Set(map, P, Desc.[[Value]], false)를 수행한다.
      2. Desc[[Writable]] 필드가 있고 Desc.[[Writable]]false이면,
        1. map.[[Delete]](P)를 수행한다.
  8. true를 반환한다.

10.4.4.3 [[Get]] ( P, Receiver )

arguments 익조틱 객체 args[[Get]] 내부 메서드는 P (프로퍼티 키), Receiver (ECMAScript 언어 값)를 인자로 받아, ECMAScript 언어 값를 포함하는 정상 완료 또는 throw completion을 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. mapargs.[[ParameterMap]]로 둔다.
  2. isMapped를 ! HasOwnProperty(map, P)로 둔다.
  3. isMappedfalse이면,
    1. OrdinaryGet(args, P, Receiver)를 반환한다.
  4. 그 외의 경우,
    1. Assert: mapP에 대한 형식 매개변수 매핑이 있음을 보장한다.
    2. Get(map, P)를 반환한다.

10.4.4.4 [[Set]] ( P, V, Receiver )

arguments 익조틱 객체 args[[Set]] 내부 메서드는 P (프로퍼티 키), V (ECMAScript 언어 값), Receiver (ECMAScript 언어 값)를 인자로 받아, 불리언을 포함하는 정상 완료 또는 throw completion을 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. SameValue(args, Receiver)가 false이면,
    1. isMappedfalse로 둔다.
  2. 그 외의 경우,
    1. mapargs.[[ParameterMap]]로 둔다.
    2. isMapped를 ! HasOwnProperty(map, P)로 둔다.
  3. isMappedtrue이면,
    1. Assert: 아래 Set은 반드시 성공한다. arguments 객체에 의해 매핑되는 형식 매개변수는 항상 writable이다.
    2. Set(map, P, V, false)를 수행한다.
  4. OrdinarySet(args, P, V, Receiver)를 반환한다.

10.4.4.5 [[Delete]] ( P )

arguments 익조틱 객체 args[[Delete]] 내부 메서드는 P (프로퍼티 키)를 인자로 받아, 불리언을 포함하는 정상 완료 또는 throw completion을 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. mapargs.[[ParameterMap]]로 둔다.
  2. isMapped를 ! HasOwnProperty(map, P)로 둔다.
  3. result를 ? OrdinaryDelete(args, P)로 둔다.
  4. resulttrue이고 isMappedtrue이면,
    1. map.[[Delete]](P)를 수행한다.
  5. result를 반환한다.

10.4.4.6 CreateUnmappedArgumentsObject ( argumentsList )

추상 연산 CreateUnmappedArgumentsObject는 argumentsList (ECMAScript 언어 값의 리스트)를 인자로 받아, 일반 객체를 반환한다. 호출 시 다음 단계를 수행한다:

  1. lenargumentsList의 요소 개수로 둔다.
  2. objOrdinaryObjectCreate(%Object.prototype%, « [[ParameterMap]] »)로 둔다.
  3. obj.[[ParameterMap]]undefined로 설정한다.
  4. DefinePropertyOrThrow(obj, "length", PropertyDescriptor { [[Value]]: 𝔽(len), [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })를 수행한다.
  5. index를 0으로 둔다.
  6. index < len인 동안 반복한다:
    1. valargumentsList[index]로 둔다.
    2. CreateDataPropertyOrThrow(obj, ! ToString(𝔽(index)), val)를 수행한다.
    3. indexindex + 1로 설정한다.
  7. DefinePropertyOrThrow(obj, %Symbol.iterator%, PropertyDescriptor { [[Value]]: %Array.prototype.values%, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })를 수행한다.
  8. DefinePropertyOrThrow(obj, "callee", PropertyDescriptor { [[Get]]: %ThrowTypeError%, [[Set]]: %ThrowTypeError%, [[Enumerable]]: false, [[Configurable]]: false })를 수행한다.
  9. obj를 반환한다.

10.4.4.7 CreateMappedArgumentsObject ( func, formals, argumentsList, env )

추상 연산 CreateMappedArgumentsObject는 func (객체), formals (파스 노드), argumentsList (ECMAScript 언어 값의 리스트), env (환경 레코드)를 인자로 받아, arguments 익조틱 객체를 반환한다. 호출 시 다음 단계를 수행한다:

  1. Assert: formals는 rest 파라미터, 바인딩 패턴, 이니셜라이저를 포함하지 않는다. 중복 식별자를 포함할 수 있다.
  2. lenargumentsList의 요소 개수로 둔다.
  3. objMakeBasicObject[[Prototype]], [[Extensible]], [[ParameterMap]] »)로 둔다.
  4. obj.[[GetOwnProperty]]10.4.4.1에 명시된 대로 설정한다.
  5. obj.[[DefineOwnProperty]]10.4.4.2에 명시된 대로 설정한다.
  6. obj.[[Get]]10.4.4.3에 명시된 대로 설정한다.
  7. obj.[[Set]]10.4.4.4에 명시된 대로 설정한다.
  8. obj.[[Delete]]10.4.4.5에 명시된 대로 설정한다.
  9. obj.[[Prototype]]%Object.prototype%로 설정한다.
  10. mapOrdinaryObjectCreate(null)로 둔다.
  11. obj.[[ParameterMap]]map으로 설정한다.
  12. parameterNamesBoundNames of formals로 둔다.
  13. numberOfParametersparameterNames의 요소 개수로 둔다.
  14. index를 0으로 둔다.
  15. index < len인 동안 반복한다:
    1. valargumentsList[index]로 둔다.
    2. CreateDataPropertyOrThrow(obj, ! ToString(𝔽(index)), val)를 수행한다.
    3. indexindex + 1로 설정한다.
  16. DefinePropertyOrThrow(obj, "length", PropertyDescriptor { [[Value]]: 𝔽(len), [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })를 수행한다.
  17. mappedNames를 새로운 빈 리스트로 둔다.
  18. indexnumberOfParameters - 1로 둔다.
  19. index ≥ 0인 동안 반복한다:
    1. nameparameterNames[index]로 둔다.
    2. mappedNamesname이 없으면,
      1. namemappedNames에 추가한다.
      2. index < len이면,
        1. gMakeArgGetter(name, env)로 둔다.
        2. pMakeArgSetter(name, env)로 둔다.
        3. map.[[DefineOwnProperty]](! ToString(𝔽(index)), PropertyDescriptor { [[Set]]: p, [[Get]]: g, [[Enumerable]]: false, [[Configurable]]: true })를 수행한다.
    3. indexindex - 1로 설정한다.
  20. DefinePropertyOrThrow(obj, %Symbol.iterator%, PropertyDescriptor { [[Value]]: %Array.prototype.values%, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })를 수행한다.
  21. DefinePropertyOrThrow(obj, "callee", PropertyDescriptor { [[Value]]: func, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true })를 수행한다.
  22. obj를 반환한다.

10.4.4.7.1 MakeArgGetter ( name, env )

추상 연산 MakeArgGetter는 name (문자열), env (환경 레코드)를 인자로 받아, 함수 객체를 반환한다. 이 연산은 env에서 name에 바인딩된 값을 반환하는 내장 함수 객체를 생성한다. 호출 시 다음 단계를 수행한다:

  1. getterClosure를, nameenv를 캡처하며, 인자가 없고, 호출 시 다음 단계를 수행하는 새로운 Abstract Closure로 둔다:
    1. NormalCompletion(! env.GetBindingValue(name, false))을 반환한다.
  2. getterCreateBuiltinFunction(getterClosure, 0, "", « »)로 둔다.
  3. 참고: getter는 ECMAScript 코드에서 직접 접근할 수 없다.
  4. getter를 반환한다.

10.4.4.7.2 MakeArgSetter ( name, env )

추상 연산 MakeArgSetter는 name (문자열), env (환경 레코드)를 인자로 받아, 함수 객체를 반환한다. 이 연산은 env에서 name에 바인딩된 값을 설정하는 내장 함수 객체를 생성한다. 호출 시 다음 단계를 수행한다:

  1. setterClosure를, nameenv를 캡처하며, (value) 인자를 받고, 호출 시 다음 단계를 수행하는 새로운 Abstract Closure로 둔다:
    1. NormalCompletion(! env.SetMutableBinding(name, value, false))을 반환한다.
  2. setterCreateBuiltinFunction(setterClosure, 1, "", « »)로 둔다.
  3. 참고: setter는 ECMAScript 코드에서 직접 접근할 수 없다.
  4. setter를 반환한다.

10.4.5 TypedArray 익조틱 객체

TypedArray익조틱 객체로, 프로퍼티 키정규 숫자 문자열인 것들을 특별하게 처리하며, 그 중 경계 내의 정수 인덱스에 해당하는 값은 균일 타입의 요소 인덱싱에 사용하고, 나머지는 프로토타입 체인 탐색 없이 존재하지 않는 것으로 강제하는 불변식을 유지합니다.

참고

어떤 Number n에 대해서도 ToString(n)은 정규 숫자 문자열이므로, 구현체는 실제로 문자열 변환을 수행하지 않고도 Number를 프로퍼티 키로 간주하여 TypedArray에 사용할 수 있습니다.

TypedArray일반 객체와 동일한 내부 슬롯을 가지며, 추가로 [[ViewedArrayBuffer]], [[TypedArrayName]], [[ContentType]], [[ByteLength]], [[ByteOffset]], [[ArrayLength]] 내부 슬롯을 가집니다.

객체의 [[PreventExtensions]], [[GetOwnProperty]], [[HasProperty]], [[DefineOwnProperty]], [[Get]], [[Set]], [[Delete]], [[OwnPropertyKeys]] 내부 메서드가 이 절의 정의를 따르고, 그 외의 필수 내부 메서드는 10.1의 정의를 따른다면, 그 객체는 TypedArray입니다. 이러한 메서드는 TypedArrayCreate로 설치됩니다.

10.4.5.1 [[PreventExtensions]] ( )

TypedArray O[[PreventExtensions]] 내부 메서드는 인자를 받지 않으며, 불리언을 포함하는 정상 완료를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. 참고: 6.1.7.3의 확장성 관련 불변식에 따라, O가 프로퍼티를 얻거나(또는 잃고 다시 얻거나) 할 수 있으면(예: 내부 버퍼가 리사이즈될 때 정수 인덱스 프로퍼티), 이 메서드는 true를 반환할 수 없습니다.
  2. IsTypedArrayFixedLength(O) 가 false이면 false를 반환합니다.
  3. OrdinaryPreventExtensions(O)를 반환합니다.

10.4.5.2 [[GetOwnProperty]] ( P )

TypedArray O[[GetOwnProperty]] 내부 메서드는 P (프로퍼티 키)를 인자로 받고, 프로퍼티 디스크립터 또는 undefined를 포함하는 정상 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. P문자열이면,
    1. numericIndexCanonicalNumericIndexString(P)로 둔다.
    2. numericIndexundefined가 아니면,
      1. valueTypedArrayGetElement(O, numericIndex)로 둔다.
      2. valueundefinedundefined를 반환한다.
      3. PropertyDescriptor { [[Value]]: value, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }를 반환한다.
  2. OrdinaryGetOwnProperty(O, P)를 반환한다.

10.4.5.3 [[HasProperty]] ( P )

TypedArray O[[HasProperty]] 내부 메서드는 P (프로퍼티 키)를 인자로 받고, 불리언 또는 throw completion을 포함하는 정상 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. P문자열이면,
    1. numericIndexCanonicalNumericIndexString(P)로 둔다.
    2. numericIndexundefined가 아니면 IsValidIntegerIndex(O, numericIndex)를 반환한다.
  2. OrdinaryHasProperty(O, P)를 반환한다.

10.4.5.4 [[DefineOwnProperty]] ( P, Desc )

TypedArray O[[DefineOwnProperty]] 내부 메서드는 P (프로퍼티 키), Desc (프로퍼티 디스크립터)를 인자로 받고, 불리언 또는 throw completion을 포함하는 정상 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. P문자열이면,
    1. numericIndexCanonicalNumericIndexString(P)로 둔다.
    2. numericIndexundefined가 아니면,
      1. IsValidIntegerIndex(O, numericIndex)가 falsefalse를 반환한다.
      2. Desc[[Configurable]] 필드가 있고 Desc.[[Configurable]]falsefalse를 반환한다.
      3. Desc[[Enumerable]] 필드가 있고 Desc.[[Enumerable]]falsefalse를 반환한다.
      4. IsAccessorDescriptor(Desc)가 truefalse를 반환한다.
      5. Desc[[Writable]] 필드가 있고 Desc.[[Writable]]falsefalse를 반환한다.
      6. Desc[[Value]] 필드가 있으면, ? TypedArraySetElement(O, numericIndex, Desc.[[Value]])를 수행한다.
      7. true를 반환한다.
  2. OrdinaryDefineOwnProperty(O, P, Desc)를 반환한다.

10.4.5.5 [[Get]] ( P, Receiver )

TypedArray O[[Get]] 내부 메서드는 P (프로퍼티 키), Receiver (ECMAScript 언어 값)를 인자로 받고, ECMAScript 언어 값 또는 throw completion을 포함하는 정상 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. P문자열이면,
    1. numericIndexCanonicalNumericIndexString(P)로 둔다.
    2. numericIndexundefined가 아니면,
      1. TypedArrayGetElement(O, numericIndex)를 반환한다.
  2. OrdinaryGet(O, P, Receiver)를 반환한다.

10.4.5.6 [[Set]] ( P, V, Receiver )

TypedArray O[[Set]] 내부 메서드는 P (프로퍼티 키), V (ECMAScript 언어 값), Receiver (ECMAScript 언어 값)를 인자로 받고, 불리언 또는 throw completion을 포함하는 정상 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. P문자열이면,
    1. numericIndexCanonicalNumericIndexString(P)로 둔다.
    2. numericIndexundefined가 아니면,
      1. SameValue(O, Receiver)가 true이면,
        1. TypedArraySetElement(O, numericIndex, V)를 수행한다.
        2. true를 반환한다.
      2. IsValidIntegerIndex(O, numericIndex)가 false이면 true를 반환한다.
  2. OrdinarySet(O, P, V, Receiver)를 반환한다.

10.4.5.7 [[Delete]] ( P )

TypedArray O[[Delete]] 내부 메서드는 P (프로퍼티 키)를 인자로 받고, 불리언을 포함하는 정상 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. P문자열이면,
    1. numericIndexCanonicalNumericIndexString(P)로 둔다.
    2. numericIndexundefined가 아니면,
      1. IsValidIntegerIndex(O, numericIndex)가 false이면 true를 반환하고, 아니면 false를 반환한다.
  2. OrdinaryDelete(O, P)를 반환한다.

10.4.5.8 [[OwnPropertyKeys]] ( )

[[OwnPropertyKeys]] 내부 메서드는 TypedArray O에 대해 인수를 받지 않으며, 정상 완성 레코드(normal completion)에 담긴 리스트(List)를 반환합니다. 반환되는 리스트는 프로퍼티 키(property keys)로 구성됩니다. 호출 시 다음 절차를 수행합니다:

  1. taRecordMakeTypedArrayWithBufferWitnessRecord(O, seq-cst)로 설정한다.
  2. keys를 새로운 비어있는 리스트(List)로 설정한다.
  3. IsTypedArrayOutOfBounds(taRecord) 가 false라면,
    1. lengthTypedArrayLength(taRecord)로 설정한다.
    2. 0 ≤ i < length를 만족하는 정수(integer) i 각각에 대해, 오름차순으로, 다음을 수행한다:
      1. ToString(𝔽(i))의 결과를 keys에 추가한다.
  4. O의 자신의 프로퍼티 키(property key) P 각각에 대해, P문자열(String)이고 P정수 인덱스(integer index)가 아닌 경우, 프로퍼티 생성의 시간 순서대로 다음을 수행한다:
    1. Pkeys에 추가한다.
  5. O의 자신의 프로퍼티 키(property key) P 각각에 대해, P심볼(Symbol)인 경우, 프로퍼티 생성의 시간 순서대로 다음을 수행한다:
    1. Pkeys에 추가한다.
  6. keys를 반환한다.

10.4.5.9 TypedArray With Buffer Witness Records

TypedArray With Buffer Witness Record레코드(Record) 값으로, TypedArray와 함께 버퍼의 바이트 길이 캐시를 캡슐화합니다. 이는 확장 가능한 SharedArrayBuffer를 볼 때, 바이트 길이 데이터 블록에 대한 단일 공유 메모리 읽기 이벤트가 보장되도록 돕기 위해 사용됩니다.

TypedArray With Buffer Witness Record에는 표 32에 나열된 필드가 있습니다.

표 32: TypedArray With Buffer Witness Record 필드
Field Name Value Meaning
[[Object]] TypedArray 바이트 길이가 로드되는 TypedArray.
[[CachedBufferByteLength]] 음수가 아닌 정수(integer) 또는 detached 레코드가 생성될 때 객체의 [[ViewedArrayBuffer]]의 바이트 길이.

10.4.5.10 MakeTypedArrayWithBufferWitnessRecord ( obj, order )

추상 연산 MakeTypedArrayWithBufferWitnessRecord는 인수 obj (TypedArray) 와 order (seq-cst 또는 unordered)를 받아 TypedArray With Buffer Witness Record를 반환합니다. 호출 시 다음 절차를 수행합니다:

  1. bufferobj.[[ViewedArrayBuffer]]로 설정한다.
  2. IsDetachedBuffer(buffer) 가 true이면,
    1. byteLengthdetached로 설정한다.
  3. 그 외의 경우,
    1. byteLengthArrayBufferByteLength(buffer, order)의 결과로 설정한다.
  4. TypedArray With Buffer Witness Record { [[Object]]: obj, [[CachedBufferByteLength]]: byteLength } 를 반환한다.

10.4.5.11 TypedArrayCreate ( prototype )

추상 연산 TypedArrayCreate는 prototype (객체)을 인수로 받아 TypedArray를 반환한다. 이는 새로운 TypedArrays를 생성하는 방법을 명시하는 데 사용된다. 호출 시 다음 단계를 수행한다:

  1. internalSlotsList를 « [[Prototype]], [[Extensible]], [[ViewedArrayBuffer]], [[TypedArrayName]], [[ContentType]], [[ByteLength]], [[ByteOffset]], [[ArrayLength]] »로 한다.
  2. AMakeBasicObject(internalSlotsList)로 한다.
  3. A.[[PreventExtensions]]10.4.5.1에 명시된 대로 설정한다.
  4. A.[[GetOwnProperty]]10.4.5.2에 명시된 대로 설정한다.
  5. A.[[HasProperty]]10.4.5.3에 명시된 대로 설정한다.
  6. A.[[DefineOwnProperty]]10.4.5.4에 명시된 대로 설정한다.
  7. A.[[Get]]10.4.5.5에 명시된 대로 설정한다.
  8. A.[[Set]]10.4.5.6에 명시된 대로 설정한다.
  9. A.[[Delete]]10.4.5.7에 명시된 대로 설정한다.
  10. A.[[OwnPropertyKeys]]10.4.5.8에 명시된 대로 설정한다.
  11. A.[[Prototype]]prototype으로 설정한다.
  12. A를 반환한다.

10.4.5.12 TypedArrayByteLength ( taRecord )

추상 연산 TypedArrayByteLength는 taRecord (TypedArray With Buffer Witness Record)를 인수로 받아 0 이상의 정수(integer)를 반환한다. 호출 시 다음 단계를 수행한다:

  1. IsTypedArrayOutOfBounds(taRecord) 가 true이면 0을 반환한다.
  2. lengthTypedArrayLength(taRecord)로 한다.
  3. length = 0이면 0을 반환한다.
  4. OtaRecord.[[Object]]로 한다.
  5. O.[[ByteLength]]auto가 아니면 O.[[ByteLength]]를 반환한다.
  6. elementSizeTypedArrayElementSize(O)로 한다.
  7. length × elementSize를 반환한다.

10.4.5.13 TypedArrayLength ( taRecord )

추상 연산 TypedArrayLength는 taRecord (TypedArray With Buffer Witness Record)를 인수로 받아 0 이상의 정수(integer)를 반환한다. 호출 시 다음 단계를 수행한다:

  1. Assert: IsTypedArrayOutOfBounds(taRecord) 는 false이다.
  2. OtaRecord.[[Object]]로 한다.
  3. O.[[ArrayLength]]auto가 아니면 O.[[ArrayLength]]를 반환한다.
  4. Assert: IsFixedLengthArrayBuffer(O.[[ViewedArrayBuffer]])는 false이다.
  5. byteOffsetO.[[ByteOffset]]로 한다.
  6. elementSizeTypedArrayElementSize(O)로 한다.
  7. byteLengthtaRecord.[[CachedBufferByteLength]]로 한다.
  8. Assert: byteLengthdetached가 아니다.
  9. floor((byteLength - byteOffset) / elementSize)를 반환한다.

10.4.5.14 IsTypedArrayOutOfBounds ( taRecord )

추상 연산 IsTypedArrayOutOfBounds는 taRecord (TypedArray With Buffer Witness Record)를 인수로 받아 불리언 값을 반환한다. 이 연산은 객체의 수치 프로퍼티가 기본 버퍼의 범위 내에 포함되지 않은 인덱스를 참조하는지 검사한다. 호출 시 다음 단계를 수행한다:

  1. OtaRecord.[[Object]]로 한다.
  2. bufferByteLengthtaRecord.[[CachedBufferByteLength]]로 한다.
  3. Assert: IsDetachedBuffer(O.[[ViewedArrayBuffer]])는 true이고 오직 bufferByteLengthdetached일 때만 그렇다.
  4. bufferByteLengthdetached이면 true를 반환한다.
  5. byteOffsetStartO.[[ByteOffset]]로 한다.
  6. O.[[ArrayLength]]auto이면,
    1. byteOffsetEndbufferByteLength로 한다.
  7. 그 외의 경우,
    1. elementSizeTypedArrayElementSize(O)로 한다.
    2. byteOffsetEndbyteOffsetStart + O.[[ArrayLength]] × elementSize로 한다.
  8. byteOffsetStart > bufferByteLength이거나 byteOffsetEnd > bufferByteLength이면 true를 반환한다.
  9. 참고: 길이가 0인 TypedArrays는 out-of-bounds로 간주하지 않는다.
  10. false를 반환한다.

10.4.5.15 IsTypedArrayFixedLength ( O )

추상 연산 IsTypedArrayFixedLength는 O (TypedArray)를 인수로 받아 불리언 값을 반환한다. 호출 시 다음 단계를 수행한다:

  1. O.[[ArrayLength]]auto이면 false를 반환한다.
  2. bufferO.[[ViewedArrayBuffer]]로 한다.
  3. IsFixedLengthArrayBuffer(buffer) 가 false이고 IsSharedArrayBuffer(buffer) 가 false이면 false를 반환한다.
  4. true를 반환한다.

10.4.5.16 IsValidIntegerIndex ( O, index )

추상 연산 IsValidIntegerIndex는 O (TypedArray)와 index (숫자)를 인수로 받아 불리언 값을 반환한다. 호출 시 다음 단계를 수행한다:

  1. IsDetachedBuffer(O.[[ViewedArrayBuffer]])가 true이면 false를 반환한다.
  2. index정수(Number)가 아니면 false를 반환한다.
  3. index-0𝔽이거나 index < -0𝔽이면 false를 반환한다.
  4. taRecordMakeTypedArrayWithBufferWitnessRecord(O, unordered)로 한다.
  5. 참고: O의 backing buffer가 확장 가능한 SharedArrayBuffer일 때 bounds 체크는 동기화 연산이 아니다.
  6. IsTypedArrayOutOfBounds(taRecord) 가 true이면 false를 반환한다.
  7. lengthTypedArrayLength(taRecord)로 한다.
  8. (index) ≥ length이면 false를 반환한다.
  9. true를 반환한다.

10.4.5.17 TypedArrayGetElement ( O, index )

추상 연산 TypedArrayGetElement는 O (TypedArray)와 index (숫자)를 인수로 받아 숫자(Number), BigInt 또는 undefined를 반환한다. 호출 시 다음 단계를 수행한다:

  1. IsValidIntegerIndex(O, index)가 false이면 undefined를 반환한다.
  2. offsetO.[[ByteOffset]]로 한다.
  3. elementSizeTypedArrayElementSize(O)로 한다.
  4. byteIndexInBuffer를 ((index) × elementSize) + offset로 한다.
  5. elementTypeTypedArrayElementType(O)로 한다.
  6. GetValueFromBuffer(O.[[ViewedArrayBuffer]], byteIndexInBuffer, elementType, true, unordered)의 결과를 반환한다.

10.4.5.18 TypedArraySetElement ( O, index, value )

추상 연산 TypedArraySetElement는 O (TypedArray), index (숫자), value (ECMAScript 언어 값)을 인수로 받아 normal completion containing unused 또는 throw completion을 반환한다. 호출 시 다음 단계를 수행한다:

  1. O.[[ContentType]]bigint이면, numValue를 ? ToBigInt(value)로 한다.
  2. 그 외에는, numValue를 ? ToNumber(value)로 한다.
  3. IsValidIntegerIndex(O, index)가 true이면,
    1. offsetO.[[ByteOffset]]로 한다.
    2. elementSizeTypedArrayElementSize(O)로 한다.
    3. byteIndexInBuffer를 ((index) × elementSize) + offset으로 한다.
    4. elementTypeTypedArrayElementType(O)로 한다.
    5. SetValueInBuffer(O.[[ViewedArrayBuffer]], byteIndexInBuffer, elementType, numValue, true, unordered)를 수행한다.
  4. unused를 반환한다.
참고

이 연산은 항상 성공하는 것처럼 보이지만, TypedArray의 끝을 넘어 쓰기를 시도하거나 분리(detached)된 ArrayBuffer를 사용하는 TypedArray에 쓰기를 시도하면 아무 효과가 없다.

10.4.5.19 IsArrayBufferViewOutOfBounds ( O )

추상 연산 IsArrayBufferViewOutOfBounds는 O (TypedArray 또는 DataView)를 인수로 받아 불리언 값을 반환한다. 이 연산은 TypedArray의 수치 프로퍼티 또는 DataView 객체의 메서드가 기본 데이터 블록의 범위 내에 포함되지 않은 인덱스를 참조할 수 있는지 검사한다. 이 추상 연산은 상위 명세에서 편의를 위해 존재한다. 호출 시 다음 단계를 수행한다:

  1. O[[DataView]] 내부 슬롯이 있으면,
    1. viewRecordMakeDataViewWithBufferWitnessRecord(O, seq-cst)로 한다.
    2. IsViewOutOfBounds(viewRecord)의 결과를 반환한다.
  2. taRecordMakeTypedArrayWithBufferWitnessRecord(O, seq-cst)로 한다.
  3. IsTypedArrayOutOfBounds(taRecord)의 결과를 반환한다.

10.4.6 모듈 네임스페이스 이그조틱 객체(Module Namespace Exotic Objects)

모듈 네임스페이스 이그조틱 객체이그조틱 객체로, ECMAScript Module에서 내보낸 바인딩을 노출합니다(자세한 내용은 16.2.3 참조). 모듈 네임스페이스 이그조틱 객체의 문자열 키를 갖는 자신의 프로퍼티와 Module이 내보낸 바인딩 이름 사이에는 일대일 대응이 있습니다. 내보낸 바인딩에는 export *로 간접적으로 내보낸 바인딩도 포함됩니다. 각 문자열 값의 자신의 프로퍼티 키는 해당 내보낸 바인딩 이름의 StringValue입니다. 이것들은 모듈 네임스페이스 이그조틱 객체의 유일한 문자열 키 프로퍼티입니다. 각 프로퍼티의 속성은 { [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: false }입니다. 모듈 네임스페이스 이그조틱 객체는 확장할 수 없습니다.

객체의 [[GetPrototypeOf]], [[SetPrototypeOf]], [[IsExtensible]], [[PreventExtensions]], [[GetOwnProperty]], [[DefineOwnProperty]], [[HasProperty]], [[Get]], [[Set]], [[Delete]], [[OwnPropertyKeys]] 내부 메서드가 이 절의 정의를 사용하고, 나머지 필수 내부 메서드는 10.1의 정의를 사용하는 경우, 그 객체는 모듈 네임스페이스 이그조틱 객체입니다. 이러한 메서드는 ModuleNamespaceCreate에 의해 설치됩니다.

모듈 네임스페이스 이그조틱 객체표 33에 정의된 내부 슬롯을 가집니다.

표 33: 모듈 네임스페이스 이그조틱 객체의 내부 슬롯
내부 슬롯 타입 설명
[[Module]] Module Record 이 네임스페이스가 내보내는 Module Record 입니다.
[[Exports]] 문자열 리스트(List) 이 객체의 자신의 프로퍼티로 노출되는 내보낸 이름의 문자열 값으로 이루어진 리스트(List)입니다. 리스트는 사전식 코드 유닛 순서로 정렬됩니다.

10.4.6.1 [[GetPrototypeOf]] ( )

모듈 네임스페이스 이그조틱 객체[[GetPrototypeOf]] 내부 메서드는 인수를 받지 않으며 정상 완성(normal completion)에 담긴 null을 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. null을 반환한다.

10.4.6.2 [[SetPrototypeOf]] ( V )

모듈 네임스페이스 이그조틱 객체 O[[SetPrototypeOf]] 내부 메서드는 V (객체 또는 null)를 인수로 받아 정상 완성(normal completion)에 담긴 불리언을 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. SetImmutablePrototype(O, V)의 결과를 반환한다.

10.4.6.3 [[IsExtensible]] ( )

모듈 네임스페이스 이그조틱 객체[[IsExtensible]] 내부 메서드는 인수를 받지 않으며 정상 완성(normal completion)에 담긴 false를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. false를 반환한다.

10.4.6.4 [[PreventExtensions]] ( )

모듈 네임스페이스 이그조틱 객체[[PreventExtensions]] 내부 메서드는 인수를 받지 않으며 정상 완성(normal completion)에 담긴 true를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. true를 반환한다.

10.4.6.5 [[GetOwnProperty]] ( P )

모듈 네임스페이스 이그조틱 객체 O[[GetOwnProperty]] 내부 메서드는 P (프로퍼티 키)를 인수로 받아 정상 완성(normal completion)에 담긴 프로퍼티 디스크립터(Property Descriptor) 또는 undefined를 반환하거나, throw completion을 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. P심볼(Symbol)이면, OrdinaryGetOwnProperty(O, P)를 반환한다.
  2. exportsO.[[Exports]]로 한다.
  3. exportsP를 포함하지 않으면 undefined를 반환한다.
  4. value를 ? O.[[Get]](P, O)로 한다.
  5. PropertyDescriptor { [[Value]]: value, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: false  }를 반환한다.

10.4.6.6 [[DefineOwnProperty]] ( P, Desc )

모듈 네임스페이스 이그조틱 객체 O[[DefineOwnProperty]] 내부 메서드는 P (프로퍼티 키)와 Desc (프로퍼티 디스크립터(Property Descriptor))를 인수로 받아 정상 완성(normal completion)에 담긴 불리언이나 throw completion을 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. P심볼(Symbol)이면, ! OrdinaryDefineOwnProperty(O, P, Desc)를 반환한다.
  2. current를 ? O.[[GetOwnProperty]](P)로 한다.
  3. currentundefined이면 false를 반환한다.
  4. Desc[[Configurable]] 필드가 있고 Desc.[[Configurable]]true이면 false를 반환한다.
  5. Desc[[Enumerable]] 필드가 있고 Desc.[[Enumerable]]false이면, false를 반환한다.
  6. IsAccessorDescriptor(Desc) 가 true이면 false를 반환한다.
  7. Desc[[Writable]] 필드가 있고 Desc.[[Writable]]false이면, false를 반환한다.
  8. Desc[[Value]] 필드가 있으면, SameValue(Desc.[[Value]], current.[[Value]])를 반환한다.
  9. true를 반환한다.

10.4.6.7 [[HasProperty]] ( P )

모듈 네임스페이스 이그조틱 객체 O[[HasProperty]] 내부 메서드는 P (프로퍼티 키)를 인수로 받아 정상 완성(normal completion)에 담긴 불리언을 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. P심볼(Symbol)이면, ! OrdinaryHasProperty(O, P)를 반환한다.
  2. exportsO.[[Exports]]로 한다.
  3. exportsP가 포함되어 있으면 true를 반환한다.
  4. false를 반환한다.

10.4.6.8 [[Get]] ( P, Receiver )

모듈 네임스페이스 이그조틱 객체 O[[Get]] 내부 메서드는 P (프로퍼티 키)와 Receiver (ECMAScript 언어 값)를 인수로 받아 정상 완성(normal completion)에 담긴 ECMAScript 언어 값 또는 throw completion을 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. P심볼(Symbol)이면,
    1. OrdinaryGet(O, P, Receiver)를 반환한다.
  2. exportsO.[[Exports]]로 한다.
  3. exportsP를 포함하지 않으면 undefined를 반환한다.
  4. mO.[[Module]]로 한다.
  5. bindingm.ResolveExport(P)로 한다.
  6. Assert: bindingResolvedBinding 레코드이다.
  7. targetModulebinding.[[Module]]로 한다.
  8. Assert: targetModuleundefined가 아니다.
  9. binding.[[BindingName]]namespace이면,
    1. GetModuleNamespace(targetModule)를 반환한다.
  10. targetEnvtargetModule.[[Environment]]로 한다.
  11. targetEnvempty이면 ReferenceError 예외를 던진다.
  12. targetEnv.GetBindingValue(binding.[[BindingName]], true)를 반환한다.
참고

ResolveExport는 부작용이 없습니다. 이 연산이 특정 exportName, resolveSet 쌍을 인수로 받아 호출될 때마다 항상 같은 결과를 반환해야 합니다. 구현체는 각 [[Exports]]에 대해 ResolveExport 결과를 미리 계산하거나 캐시할 수 있습니다.

10.4.6.9 [[Set]] ( P, V, Receiver )

모듈 네임스페이스 이그조틱 객체[[Set]] 내부 메서드는 P (프로퍼티 키), V (ECMAScript 언어 값), Receiver (ECMAScript 언어 값)를 인수로 받아 정상 완성(normal completion)에 담긴 false를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. false를 반환한다.

10.4.6.10 [[Delete]] ( P )

모듈 네임스페이스 이그조틱 객체 O[[Delete]] 내부 메서드는 P (프로퍼티 키)를 인수로 받아 정상 완성(normal completion)에 담긴 불리언을 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. P심볼(Symbol)이면,
    1. OrdinaryDelete(O, P)를 반환한다.
  2. exportsO.[[Exports]]로 한다.
  3. exportsP가 포함되어 있으면 false를 반환한다.
  4. true를 반환한다.

10.4.6.11 [[OwnPropertyKeys]] ( )

모듈 네임스페이스 이그조틱 객체 O[[OwnPropertyKeys]] 내부 메서드는 인수를 받지 않으며, 정상 완성(normal completion)에 담긴 프로퍼티 키의 리스트(List)를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. exportsO.[[Exports]]로 한다.
  2. symbolKeysOrdinaryOwnPropertyKeys(O)로 한다.
  3. exportssymbolKeys리스트 연결(list-concatenation) 결과를 반환한다.

10.4.6.12 ModuleNamespaceCreate ( module, exports )

추상 연산 ModuleNamespaceCreate는 module (Module Record)와 exports (문자열의 리스트(List))를 인수로 받아 module namespace exotic object를 반환한다. 이는 새로운 module namespace exotic objects의 생성을 명시하는 데 사용된다. 호출 시 다음 절차를 수행한다:

  1. Assert: module.[[Namespace]]empty이다.
  2. internalSlotsList표 33에 나열된 내부 슬롯들로 한다.
  3. MMakeBasicObject(internalSlotsList)로 한다.
  4. M의 필수 내부 메서드들을 10.4.6에 명시된 정의로 설정한다.
  5. M.[[Module]]module을 할당한다.
  6. sortedExportsexports의 요소들을 lexicographic code unit order에 따라 정렬한 리스트(List)로 한다.
  7. M.[[Exports]]sortedExports를 할당한다.
  8. 28.3에 정의된 대로 M의 자신의 프로퍼티들을 생성한다.
  9. module.[[Namespace]]M을 할당한다.
  10. M을 반환한다.

10.4.7 불변 프로토타입 이그조틱 객체(Immutable Prototype Exotic Objects)

불변 프로토타입 이그조틱 객체이그조틱 객체이며, 초기화된 후 변경되지 않는 [[Prototype]] 내부 슬롯을 가진다.

객체의 [[SetPrototypeOf]] 내부 메서드가 다음 구현을 사용할 때, 그 객체는 불변 프로토타입 이그조틱 객체이다. (다른 필수 내부 메서드는 구체적인 불변 프로토타입 이그조틱 객체에 따라 임의의 구현을 사용할 수 있다.)

참고

다른 이그조틱 객체와 달리, 불변 프로토타입 이그조틱 객체에 대해 별도의 생성 추상 연산이 제공되지 않는다. 이는 이 객체들이 %Object.prototype%호스트 환경에서만 사용되며, 호스트 환경에서는 관련 객체가 다른 방식으로 이그조틱할 수 있으므로 별도의 생성 연산이 필요하기 때문이다.

10.4.7.1 [[SetPrototypeOf]] ( V )

불변 프로토타입 이그조틱 객체 O[[SetPrototypeOf]] 내부 메서드는 인수 V (객체 또는 null)를 받아 정상 완료(normal completion) 불리언 또는 throw completion을 반환한다. 호출 시 다음 절차를 수행한다:

  1. SetImmutablePrototype(O, V)를 반환한다.

10.4.7.2 SetImmutablePrototype ( O, V )

추상 연산 SetImmutablePrototype은 O (객체)와 V (객체 또는 null)를 인수로 받아 정상 완료(normal completion) 불리언 또는 throw completion을 반환한다. 호출 시 다음 절차를 수행한다:

  1. current를 ? O.[[GetPrototypeOf]]()로 한다.
  2. SameValue(V, current)가 true이면 true를 반환한다.
  3. false를 반환한다.

10.5 프록시 객체 내부 메서드 및 내부 슬롯

프록시 객체는 익조틱 객체로, 필수 내부 메서드가 부분적으로 ECMAScript 코드로 구현되어 있습니다. 모든 프록시 객체는 [[ProxyHandler]]라는 내부 슬롯을 가집니다. [[ProxyHandler]]의 값은 프록시의 핸들러 객체라 불리는 객체이거나 null입니다. 핸들러 객체의 메서드들(표 34 참고)은 하나 이상의 프록시 객체 내부 메서드의 구현을 보강하는 데 사용될 수 있습니다. 모든 프록시 객체는 또한 [[ProxyTarget]]이라는 내부 슬롯을 가지며, 그 값은 객체이거나 null입니다. 이 객체를 프록시의 타겟 객체라고 합니다.

객체가 필수 내부 메서드([[Call]][[Construct]]를 포함, 해당되는 경우) 구현에 이 절의 정의를 사용하는 경우, 해당 객체를 프록시 익조틱 객체라고 합니다. 이러한 내부 메서드는 ProxyCreate에서 설치됩니다.

표 34: 프록시 핸들러 메서드
내부 메서드 핸들러 메서드
[[GetPrototypeOf]] getPrototypeOf
[[SetPrototypeOf]] setPrototypeOf
[[IsExtensible]] isExtensible
[[PreventExtensions]] preventExtensions
[[GetOwnProperty]] getOwnPropertyDescriptor
[[DefineOwnProperty]] defineProperty
[[HasProperty]] has
[[Get]] get
[[Set]] set
[[Delete]] deleteProperty
[[OwnPropertyKeys]] ownKeys
[[Call]] apply
[[Construct]] construct

핸들러 메서드가 프록시 객체 내부 메서드의 구현을 제공하기 위해 호출될 때, 핸들러 메서드에는 프록시의 타겟 객체가 인자로 전달됩니다. 프록시의 핸들러 객체는 모든 필수 내부 메서드에 해당하는 메서드를 반드시 가질 필요는 없습니다. 프록시에 대해 내부 메서드를 호출할 때 핸들러 객체에 해당 트랩 메서드가 없으면, 프록시의 타겟 객체의 해당 내부 메서드가 호출됩니다.

프록시 객체의 [[ProxyHandler]][[ProxyTarget]] 내부 슬롯은 객체가 생성될 때 항상 초기화되며 일반적으로 수정할 수 없습니다. 일부 프록시 객체는 이후에 해제(revoke)될 수 있도록 생성됩니다. 프록시가 해제되면 해당 프록시의 [[ProxyHandler]][[ProxyTarget]] 내부 슬롯이 null로 설정되어, 이후 해당 프록시 객체의 내부 메서드 호출 시 TypeError 예외가 발생하게 됩니다.

프록시 객체는 내부 메서드의 구현을 임의의 ECMAScript 코드로 제공할 수 있으므로, 핸들러 메서드가 6.1.7.3에 정의된 불변 조건(invariant)을 위반하는 프록시 객체를 정의하는 것도 가능합니다. 6.1.7.3에 정의된 일부 내부 메서드 불변 조건은 본질적인 무결성 불변 조건입니다. 이러한 불변 조건은 본 절에 명시된 프록시 객체 내부 메서드에 의해 명시적으로 강제됩니다. ECMAScript 구현체는 모든 가능한 불변 조건 위반에도 견고해야 합니다.

다음 알고리즘 설명에서, O는 ECMAScript 프록시 객체, P프로퍼티 키 값, VECMAScript 언어 값, Desc프로퍼티 디스크립터 레코드라고 가정합니다.

10.5.1 [[GetPrototypeOf]] ( )

프록시 익조틱 객체 O[[GetPrototypeOf]] 내부 메서드는 인자를 받지 않으며, 객체 또는 null을 포함하는 정상 완료이거나 예외 완료를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. ValidateNonRevokedProxy(O)를 수행한다.
  2. targetO.[[ProxyTarget]]로 한다.
  3. handlerO.[[ProxyHandler]]로 한다.
  4. Assert: handler객체이다.
  5. trap을 ? GetMethod(handler, "getPrototypeOf")로 한다.
  6. trapundefined이면,
    1. target.[[GetPrototypeOf]]()를 반환한다.
  7. handlerProto를 ? Call(trap, handler, « target »)로 한다.
  8. handlerProto객체가 아니고 null도 아니면, TypeError 예외를 발생시킨다.
  9. extensibleTarget을 ? IsExtensible(target)로 한다.
  10. extensibleTargettrue이면 handlerProto를 반환한다.
  11. targetProto를 ? target.[[GetPrototypeOf]]()로 한다.
  12. SameValue(handlerProto, targetProto)가 false이면, TypeError 예외를 발생시킨다.
  13. handlerProto를 반환한다.
참고

프록시 객체의 [[GetPrototypeOf]]는 다음 불변 조건을 강제합니다:

  • [[GetPrototypeOf]]의 결과는 객체 또는 null이어야 합니다.
  • 타겟 객체가 확장 가능하지 않은 경우, 프록시 객체에 적용된 [[GetPrototypeOf]]는 타겟 객체에 적용된 [[GetPrototypeOf]]와 동일한 값을 반환해야 합니다.

10.5.2 [[SetPrototypeOf]] ( V )

프록시 익조틱 객체 O[[SetPrototypeOf]] 내부 메서드는 인자 V(객체 또는 null)를 받고, 불리언을 포함하는 정상 완료이거나 예외 완료를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. ValidateNonRevokedProxy(O)를 수행한다.
  2. targetO.[[ProxyTarget]]로 한다.
  3. handlerO.[[ProxyHandler]]로 한다.
  4. Assert: handler객체이다.
  5. trap을 ? GetMethod(handler, "setPrototypeOf")로 한다.
  6. trapundefined이면,
    1. target.[[SetPrototypeOf]](V)를 반환한다.
  7. booleanTrapResultToBoolean(? Call(trap, handler, « target, V »))로 한다.
  8. booleanTrapResultfalse이면 false를 반환한다.
  9. extensibleTarget을 ? IsExtensible(target)로 한다.
  10. extensibleTargettrue이면 true를 반환한다.
  11. targetProto를 ? target.[[GetPrototypeOf]]()로 한다.
  12. SameValue(V, targetProto)가 false이면 TypeError 예외를 발생시킨다.
  13. true를 반환한다.
참고

프록시 객체의 [[SetPrototypeOf]]는 다음 불변 조건을 강제합니다:

  • [[SetPrototypeOf]]의 결과는 불리언 값이어야 합니다.
  • 타겟 객체가 확장 가능하지 않은 경우, 인자 값은 타겟 객체에 적용된 [[GetPrototypeOf]]의 결과와 동일해야 합니다.

10.5.3 [[IsExtensible]] ( )

프록시 익조틱 객체 O[[IsExtensible]] 내부 메서드는 인자를 받지 않으며, 불리언을 포함하는 정상 완료이거나 예외 완료를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. ValidateNonRevokedProxy(O)를 수행한다.
  2. targetO.[[ProxyTarget]]로 한다.
  3. handlerO.[[ProxyHandler]]로 한다.
  4. Assert: handler객체이다.
  5. trap을 ? GetMethod(handler, "isExtensible")로 한다.
  6. trapundefined이면,
    1. IsExtensible(target)을 반환한다.
  7. booleanTrapResultToBoolean(? Call(trap, handler, « target »))로 한다.
  8. targetResult를 ? IsExtensible(target)로 한다.
  9. booleanTrapResulttargetResult와 다르면 TypeError 예외를 발생시킨다.
  10. booleanTrapResult를 반환한다.
참고

프록시 객체의 [[IsExtensible]]는 다음 불변 조건을 강제합니다:

  • [[IsExtensible]]의 결과는 불리언 값이어야 합니다.
  • 프록시 객체에 적용된 [[IsExtensible]]는 동일한 인자와 함께 프록시 객체의 타겟 객체에 적용된 [[IsExtensible]]와 동일한 값을 반환해야 합니다.

10.5.4 [[PreventExtensions]] ( )

프록시 익조틱 객체 O[[PreventExtensions]] 내부 메서드는 인자를 받지 않으며, 불리언을 포함하는 정상 완료이거나 예외 완료를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. ValidateNonRevokedProxy(O)를 수행한다.
  2. targetO.[[ProxyTarget]]로 한다.
  3. handlerO.[[ProxyHandler]]로 한다.
  4. Assert: handler객체이다.
  5. trap을 ? GetMethod(handler, "preventExtensions")로 한다.
  6. trapundefined이면,
    1. target.[[PreventExtensions]]()를 반환한다.
  7. booleanTrapResultToBoolean(? Call(trap, handler, « target »))로 한다.
  8. booleanTrapResulttrue이면,
    1. extensibleTarget을 ? IsExtensible(target)로 한다.
    2. extensibleTargettrue이면 TypeError 예외를 발생시킨다.
  9. booleanTrapResult를 반환한다.
참고

프록시 객체의 [[PreventExtensions]]는 다음 불변 조건을 강제합니다:

  • [[PreventExtensions]]의 결과는 불리언 값이어야 합니다.
  • 프록시 객체에 적용된 [[PreventExtensions]]는 프록시 객체의 타겟 객체에 적용된 [[IsExtensible]]false일 때만 true를 반환합니다.

10.5.5 [[GetOwnProperty]] ( P )

프록시 익조틱 객체 O[[GetOwnProperty]] 내부 메서드는 인자 P (프로퍼티 키)를 받고, 정상 완료프로퍼티 디스크립터 또는 undefined을, 혹은 예외 완료를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. ValidateNonRevokedProxy(O)를 수행한다.
  2. targetO.[[ProxyTarget]]로 한다.
  3. handlerO.[[ProxyHandler]]로 한다.
  4. Assert: handler객체이다.
  5. trap을 ? GetMethod(handler, "getOwnPropertyDescriptor")로 한다.
  6. trapundefined이면,
    1. target.[[GetOwnProperty]](P)를 반환한다.
  7. trapResultObj를 ? Call(trap, handler, « target, P »)로 한다.
  8. trapResultObj객체가 아니고 undefined도 아니면, TypeError 예외를 발생시킨다.
  9. targetDesc를 ? target.[[GetOwnProperty]](P)로 한다.
  10. trapResultObjundefined이면,
    1. targetDescundefined이면 undefined를 반환한다.
    2. targetDesc.[[Configurable]]false이면 TypeError 예외를 발생시킨다.
    3. extensibleTarget를 ? IsExtensible(target)로 한다.
    4. extensibleTargetfalse이면 TypeError 예외를 발생시킨다.
    5. undefined를 반환한다.
  11. extensibleTarget를 ? IsExtensible(target)로 한다.
  12. resultDesc를 ? ToPropertyDescriptor(trapResultObj)로 한다.
  13. CompletePropertyDescriptor(resultDesc)를 수행한다.
  14. validIsCompatiblePropertyDescriptor(extensibleTarget, resultDesc, targetDesc)로 한다.
  15. validfalse이면 TypeError 예외를 발생시킨다.
  16. resultDesc.[[Configurable]]false이면,
    1. targetDescundefined이거나 targetDesc.[[Configurable]]true이면,
      1. TypeError 예외를 발생시킨다.
    2. resultDesc[[Writable]] 필드를 가지고 resultDesc.[[Writable]]false이면,
      1. Assert: targetDesc[[Writable]] 필드를 가진다.
      2. targetDesc.[[Writable]]true이면 TypeError 예외를 발생시킨다.
  17. resultDesc를 반환한다.
참고

프록시 객체의 [[GetOwnProperty]]는 다음 불변 조건을 강제합니다:

  • [[GetOwnProperty]]의 결과는 객체 또는 undefined여야 합니다.
  • 타겟 객체에 비구성 가능(Non-configurable) 자체 프로퍼티가 존재할 때, 해당 프로퍼티는 존재하지 않는 것으로 보고될 수 없습니다.
  • 타겟 객체가 확장 불가능(Non-extensible)하고 해당 프로퍼티가 자체 프로퍼티로 존재할 때, 해당 프로퍼티는 존재하지 않는 것으로 보고될 수 없습니다.
  • 타겟 객체가 확장 불가능하고 해당 프로퍼티가 자체 프로퍼티로 존재하지 않는 경우, 해당 프로퍼티는 존재하는 것으로 보고될 수 없습니다.
  • 타겟 객체에 비구성 가능 자체 프로퍼티가 존재하지 않는 한, 프로퍼티를 비구성 가능으로 보고할 수 없습니다.
  • 타겟 객체에 비구성 가능, 비쓰기 가능(non-writable) 자체 프로퍼티가 존재하지 않는 한, 프로퍼티를 동시에 비구성 가능 및 비쓰기 가능으로 보고할 수 없습니다.

10.5.6 [[DefineOwnProperty]] ( P, Desc )

프록시 익조틱 객체 O[[DefineOwnProperty]] 내부 메서드는 인자 P (프로퍼티 키)와 Desc (프로퍼티 디스크립터)를 받아 정상 완료로 불리언을, 혹은 예외 완료를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. ValidateNonRevokedProxy(O)를 수행한다.
  2. targetO.[[ProxyTarget]]로 한다.
  3. handlerO.[[ProxyHandler]]로 한다.
  4. Assert: handler객체이다.
  5. trap을 ? GetMethod(handler, "defineProperty")로 한다.
  6. trapundefined이면,
    1. target.[[DefineOwnProperty]](P, Desc)를 반환한다.
  7. descObjFromPropertyDescriptor(Desc)로 한다.
  8. booleanTrapResultToBoolean(? Call(trap, handler, « target, P, descObj »))로 한다.
  9. booleanTrapResultfalse이면 false를 반환한다.
  10. targetDesc를 ? target.[[GetOwnProperty]](P)로 한다.
  11. extensibleTarget를 ? IsExtensible(target)로 한다.
  12. Desc[[Configurable]] 필드를 가지고 Desc.[[Configurable]]false이면,
    1. settingConfigFalsetrue로 한다.
  13. 그 외에는,
    1. settingConfigFalsefalse로 한다.
  14. targetDescundefined이면,
    1. extensibleTargetfalse이면 TypeError 예외를 발생시킨다.
    2. settingConfigFalsetrue이면 TypeError 예외를 발생시킨다.
  15. 그 외에는,
    1. IsCompatiblePropertyDescriptor(extensibleTarget, Desc, targetDesc)가 false이면 TypeError 예외를 발생시킨다.
    2. settingConfigFalsetrue이고 targetDesc.[[Configurable]]true이면 TypeError 예외를 발생시킨다.
    3. IsDataDescriptor(targetDesc) 가 true이고 targetDesc.[[Configurable]]false이며 targetDesc.[[Writable]]true이면,
      1. Desc[[Writable]] 필드를 가지고 Desc.[[Writable]]false이면 TypeError 예외를 발생시킨다.
  16. true를 반환한다.
참고

프록시 객체의 [[DefineOwnProperty]]는 다음 불변 조건을 강제합니다:

  • [[DefineOwnProperty]]의 결과는 불리언 값이어야 합니다.
  • 타겟 객체가 확장 불가능하면 프로퍼티를 추가할 수 없습니다.
  • 타겟 객체에 해당하는 비구성 가능 자체 프로퍼티가 존재하지 않는 한, 프로퍼티를 비구성 가능으로 만들 수 없습니다.
  • 타겟 객체에 해당하는 비구성 가능, 비쓰기 가능 자체 프로퍼티가 존재하지 않는 한, 비구성 가능 프로퍼티를 비쓰기 가능으로 만들 수 없습니다.
  • 프로퍼티에 해당하는 타겟 객체 프로퍼티가 존재할 때, 그 프로퍼티의 프로퍼티 디스크립터[[DefineOwnProperty]]로 적용해도 예외가 발생하지 않아야 합니다.

10.5.7 [[HasProperty]] ( P )

프록시 익조틱 객체 O[[HasProperty]] 내부 메서드는 인자 P (프로퍼티 키)를 받고, 정상 완료로 불리언을, 혹은 예외 완료를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. ValidateNonRevokedProxy(O)를 수행한다.
  2. targetO.[[ProxyTarget]]로 한다.
  3. handlerO.[[ProxyHandler]]로 한다.
  4. Assert: handler객체이다.
  5. trap을 ? GetMethod(handler, "has")로 한다.
  6. trapundefined이면,
    1. target.[[HasProperty]](P)를 반환한다.
  7. booleanTrapResultToBoolean(? Call(trap, handler, « target, P »))로 한다.
  8. booleanTrapResultfalse이면,
    1. targetDesc를 ? target.[[GetOwnProperty]](P)로 한다.
    2. targetDescundefined가 아니면,
      1. targetDesc.[[Configurable]]false이면 TypeError 예외를 발생시킨다.
      2. extensibleTarget를 ? IsExtensible(target)로 한다.
      3. extensibleTargetfalse이면 TypeError 예외를 발생시킨다.
  9. booleanTrapResult를 반환한다.
참고

프록시 객체의 [[HasProperty]]는 다음 불변 조건을 강제합니다:

  • [[HasProperty]]의 결과는 불리언 값이어야 합니다.
  • 타겟 객체에 비구성 가능 자체 프로퍼티가 존재할 때, 해당 프로퍼티는 존재하지 않는 것으로 보고될 수 없습니다.
  • 타겟 객체가 확장 불가능하고 해당 프로퍼티가 자체 프로퍼티로 존재할 때, 해당 프로퍼티는 존재하지 않는 것으로 보고될 수 없습니다.

10.5.8 [[Get]] ( P, Receiver )

프록시 익조틱 객체 O[[Get]] 내부 메서드는 인자 P (프로퍼티 키)와 Receiver (ECMAScript 언어 값)를 받고, 정상 완료ECMAScript 언어 값을, 혹은 예외 완료를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. ValidateNonRevokedProxy(O)를 수행한다.
  2. targetO.[[ProxyTarget]]로 한다.
  3. handlerO.[[ProxyHandler]]로 한다.
  4. Assert: handler객체이다.
  5. trap을 ? GetMethod(handler, "get")로 한다.
  6. trapundefined이면,
    1. target.[[Get]](P, Receiver)를 반환한다.
  7. trapResult를 ? Call(trap, handler, « target, P, Receiver »)로 한다.
  8. targetDesc를 ? target.[[GetOwnProperty]](P)로 한다.
  9. targetDescundefined가 아니고 targetDesc.[[Configurable]]false이면,
    1. IsDataDescriptor(targetDesc) 가 true이고 targetDesc.[[Writable]]false이면,
      1. SameValue(trapResult, targetDesc.[[Value]])가 false이면 TypeError 예외를 발생시킨다.
    2. IsAccessorDescriptor(targetDesc) 가 true이고 targetDesc.[[Get]]undefined이면,
      1. trapResultundefined가 아니면 TypeError 예외를 발생시킨다.
  10. trapResult를 반환한다.
참고

프록시 객체의 [[Get]]는 다음 불변 조건을 강제합니다:

  • 비쓰기 가능, 비구성 가능 자체 데이터 프로퍼티의 경우, 해당 프로퍼티에 대해 보고되는 값은 타겟 객체 프로퍼티의 값과 같아야 합니다.
  • 접근자 프로퍼티이면서 [[Get]] 속성이 undefined인 비구성 가능 자체 프로퍼티의 경우, 해당 프로퍼티에 대해 보고되는 값은 undefined여야 합니다.

10.5.9 [[Set]] ( P, V, Receiver )

프록시 익조틱 객체 O[[Set]] 내부 메서드는 P(프로퍼티 키), V(ECMAScript 언어 값), Receiver(ECMAScript 언어 값)을 인자로 받고, 불리언을 포함하는 정상 완료 또는 예외 완료를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. ValidateNonRevokedProxy(O)를 수행한다.
  2. targetO.[[ProxyTarget]]로 한다.
  3. handlerO.[[ProxyHandler]]로 한다.
  4. Assert: handler객체이다.
  5. trap을 ? GetMethod(handler, "set")로 한다.
  6. trapundefined이면,
    1. target.[[Set]](P, V, Receiver)를 반환한다.
  7. booleanTrapResultToBoolean(? Call(trap, handler, « target, P, V, Receiver »))로 한다.
  8. booleanTrapResultfalse이면 false를 반환한다.
  9. targetDesc를 ? target.[[GetOwnProperty]](P)로 한다.
  10. targetDescundefined가 아니고 targetDesc.[[Configurable]]false이면,
    1. IsDataDescriptor(targetDesc) 가 true이고 targetDesc.[[Writable]]false이면,
      1. SameValue(V, targetDesc.[[Value]])가 false이면 TypeError 예외를 발생시킨다.
    2. IsAccessorDescriptor(targetDesc) 가 true이면,
      1. targetDesc.[[Set]]undefined이면 TypeError 예외를 발생시킨다.
  11. true를 반환한다.
참고

프록시 객체의 [[Set]]는 다음 불변 조건을 강제합니다:

  • [[Set]]의 결과는 불리언 값이어야 합니다.
  • 타겟 객체의 해당 프로퍼티가 비가변(non-configurable) 및 비가변(non-writable) 자체 데이터 프로퍼티인 경우, 해당 프로퍼티의 값을 타겟 객체의 값과 다르게 변경할 수 없습니다.
  • 타겟 객체의 해당 프로퍼티가 비가변(non-configurable) 자체 접근자 프로퍼티이고, 그 [[Set]] 속성이 undefined인 경우 해당 프로퍼티 값을 설정할 수 없습니다.

10.5.10 [[Delete]] ( P )

프록시 익조틱 객체 O[[Delete]] 내부 메서드는 P(프로퍼티 키)를 인자로 받고, 불리언을 포함하는 정상 완료 또는 예외 완료를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. ValidateNonRevokedProxy(O)를 수행한다.
  2. targetO.[[ProxyTarget]]로 한다.
  3. handlerO.[[ProxyHandler]]로 한다.
  4. Assert: handler객체이다.
  5. trap을 ? GetMethod(handler, "deleteProperty")로 한다.
  6. trapundefined이면,
    1. target.[[Delete]](P)를 반환한다.
  7. booleanTrapResultToBoolean(? Call(trap, handler, « target, P »))로 한다.
  8. booleanTrapResultfalse이면 false를 반환한다.
  9. targetDesc를 ? target.[[GetOwnProperty]](P)로 한다.
  10. targetDescundefined이면 true를 반환한다.
  11. targetDesc.[[Configurable]]false이면 TypeError 예외를 발생시킨다.
  12. extensibleTarget를 ? IsExtensible(target)로 한다.
  13. extensibleTargetfalse이면 TypeError 예외를 발생시킨다.
  14. true를 반환한다.
참고

프록시 객체의 [[Delete]]는 다음 불변 조건을 강제합니다:

  • [[Delete]]의 결과는 불리언 값입니다.
  • 타겟 객체에 비가변(non-configurable) 자체 프로퍼티로 존재하는 경우, 해당 프로퍼티가 삭제된 것으로 보고할 수 없습니다.
  • 타겟 객체에 자체 프로퍼티로 존재하고, 타겟 객체가 비확장 가능(non-extensible)한 경우, 해당 프로퍼티가 삭제된 것으로 보고할 수 없습니다.

10.5.11 [[OwnPropertyKeys]] ( )

프록시 익조틱 객체 O[[OwnPropertyKeys]] 내부 메서드는 인자를 받지 않으며, 프로퍼티 키들의 List를 포함하는 정상 완료 또는 예외 완료를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. ValidateNonRevokedProxy(O)를 수행한다.
  2. targetO.[[ProxyTarget]]로 한다.
  3. handlerO.[[ProxyHandler]]로 한다.
  4. Assert: handler객체이다.
  5. trap을 ? GetMethod(handler, "ownKeys")로 한다.
  6. trapundefined이면,
    1. target.[[OwnPropertyKeys]]()를 반환한다.
  7. trapResultArray를 ? Call(trap, handler, « target »))로 한다.
  8. trapResult를 ? CreateListFromArrayLike(trapResultArray, property-key)로 한다.
  9. trapResult가 중복 항목을 포함하면 TypeError 예외를 발생시킨다.
  10. extensibleTarget를 ? IsExtensible(target)로 한다.
  11. targetKeys를 ? target.[[OwnPropertyKeys]]()로 한다.
  12. Assert: targetKeys프로퍼티 키들의 List이다.
  13. Assert: targetKeys는 중복 항목을 포함하지 않는다.
  14. targetConfigurableKeys를 새로운 빈 List로 한다.
  15. targetNonconfigurableKeys를 새로운 빈 List로 한다.
  16. targetKeys의 각 요소 key에 대해, 다음을 수행한다:
    1. desc를 ? target.[[GetOwnProperty]](key)로 한다.
    2. descundefined가 아니고 desc.[[Configurable]]false이면,
      1. keytargetNonconfigurableKeys에 추가한다.
    3. 그 외에는,
      1. keytargetConfigurableKeys에 추가한다.
  17. extensibleTargettrue이고 targetNonconfigurableKeys가 비어 있으면,
    1. trapResult를 반환한다.
  18. uncheckedResultKeystrapResult의 요소들로 이루어진 List로 한다.
  19. targetNonconfigurableKeys의 각 요소 key에 대해, 다음을 수행한다:
    1. uncheckedResultKeyskey가 없으면 TypeError 예외를 발생시킨다.
    2. keyuncheckedResultKeys에서 제거한다.
  20. extensibleTargettrue이면 trapResult를 반환한다.
  21. targetConfigurableKeys의 각 요소 key에 대해, 다음을 수행한다:
    1. uncheckedResultKeyskey가 없으면 TypeError 예외를 발생시킨다.
    2. keyuncheckedResultKeys에서 제거한다.
  22. uncheckedResultKeys가 비어 있지 않으면 TypeError 예외를 발생시킨다.
  23. trapResult를 반환한다.
참고

프록시 객체의 [[OwnPropertyKeys]]는 다음 불변 조건을 강제합니다:

  • [[OwnPropertyKeys]]의 결과는 List입니다.
  • 반환된 List에는 중복 항목이 없어야 합니다.
  • 반환된 List의 각 요소는 프로퍼티 키여야 합니다.
  • 결과 List에는 타겟 객체의 모든 비가변 자체 프로퍼티의 키가 포함되어야 합니다.
  • 타겟 객체가 비확장 가능(non-extensible)한 경우, 결과 List에는 타겟 객체의 모든 자체 프로퍼티의 키만 포함되어야 하며, 다른 값은 포함될 수 없습니다.

10.5.12 [[Call]] ( thisArgument, argumentsList )

프록시 익조틱 객체 O[[Call]] 내부 메서드는 thisArgument(ECMAScript 언어 값), argumentsList(ECMAScript 언어 값들의 List)를 인자로 받고, ECMAScript 언어 값을 포함하는 정상 완료 또는 예외 완료를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. ValidateNonRevokedProxy(O)를 수행한다.
  2. targetO.[[ProxyTarget]]로 한다.
  3. handlerO.[[ProxyHandler]]로 한다.
  4. Assert: handler객체이다.
  5. trap을 ? GetMethod(handler, "apply")로 한다.
  6. trapundefined이면,
    1. Call(target, thisArgument, argumentsList)를 반환한다.
  7. argArrayCreateArrayFromList(argumentsList)로 한다.
  8. Call(trap, handler, « target, thisArgument, argArray »)를 반환한다.
참고

프록시 익조틱 객체[[ProxyTarget]] 내부 슬롯의 초기 값이 [[Call]] 내부 메서드를 가진 객체인 경우에만 [[Call]] 내부 메서드를 가집니다.

10.5.13 [[Construct]] ( argumentsList, newTarget )

프록시 익조틱 객체 O[[Construct]] 내부 메서드는 argumentsList(ECMAScript 언어 값들의 List), newTarget(생성자)를 인자로 받고, 객체를 포함하는 정상 완료 또는 예외 완료를 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. ValidateNonRevokedProxy(O)를 수행한다.
  2. targetO.[[ProxyTarget]]로 한다.
  3. Assert: IsConstructor(target)가 true임을 확인한다.
  4. handlerO.[[ProxyHandler]]로 한다.
  5. Assert: handler객체이다.
  6. trap을 ? GetMethod(handler, "construct")로 한다.
  7. trapundefined이면,
    1. Construct(target, argumentsList, newTarget)를 반환한다.
  8. argArrayCreateArrayFromList(argumentsList)로 한다.
  9. newObj를 ? Call(trap, handler, « target, argArray, newTarget »)로 한다.
  10. newObj객체가 아니면 TypeError 예외를 발생시킨다.
  11. newObj를 반환한다.
참고 1

프록시 익조틱 객체[[ProxyTarget]] 내부 슬롯의 초기 값이 [[Construct]] 내부 메서드를 가진 객체인 경우에만 [[Construct]] 내부 메서드를 가집니다.

참고 2

프록시 객체의 [[Construct]]는 다음 불변 조건을 강제합니다:

  • [[Construct]]의 결과는 반드시 객체여야 합니다.

10.5.14 ValidateNonRevokedProxy ( proxy )

추상 연산 ValidateNonRevokedProxy는 인자 proxy(프록시 익조틱 객체)를 받고, unused를 포함하는 정상 완료 또는 예외 완료를 반환합니다. proxy가 해제(revoked)된 경우 TypeError 예외를 발생시킵니다. 호출 시 다음 단계를 수행합니다:

  1. proxy.[[ProxyTarget]]null이면, TypeError 예외를 발생시킨다.
  2. Assert: proxy.[[ProxyHandler]]null이 아니다.
  3. unused를 반환한다.

10.5.15 ProxyCreate ( target, handler )

추상 연산 ProxyCreate는 인자 target(ECMAScript 언어 값)과 handler(ECMAScript 언어 값)를 받고, 프록시 익조틱 객체를 포함하는 정상 완료 또는 예외 완료를 반환합니다. 새로운 프록시 객체를 생성할 때 사용됩니다. 호출 시 다음 단계를 수행합니다:

  1. target객체가 아니면, TypeError 예외를 발생시킨다.
  2. handler객체가 아니면, TypeError 예외를 발생시킨다.
  3. PMakeBasicObject[[ProxyHandler]], [[ProxyTarget]] »)로 한다.
  4. P의 필수 내부 메서드들([[Call]][[Construct]] 제외)에 10.5에 지정된 정의를 설정한다.
  5. IsCallable(target)이 true이면,
    1. P.[[Call]]10.5.12에 명시된 대로 설정한다.
    2. IsConstructor(target) 이 true이면,
      1. P.[[Construct]]10.5.13에 명시된 대로 설정한다.
  6. P.[[ProxyTarget]]target으로 설정한다.
  7. P.[[ProxyHandler]]handler로 설정한다.
  8. P를 반환한다.

11 ECMAScript 언어: 소스 텍스트

11.1 소스 텍스트

구문

SourceCharacter :: 임의의 유니코드 코드 포인트

ECMAScript 소스 텍스트는 유니코드 코드 포인트들의 시퀀스이다. U+0000부터 U+10FFFF까지의 모든 유니코드 코드 포인트 값(서러게이트 코드 포인트 포함)은 ECMAScript 문법에서 허용되는 곳에 ECMAScript 소스 텍스트에 나타날 수 있다. ECMAScript 소스 텍스트를 저장하고 교환하는 데 사용되는 실제 인코딩은 이 명세와 관련없다. 외부 소스 텍스트 인코딩과 무관하게, 표준 ECMAScript 구현체는 소스 텍스트를 동등한 SourceCharacter 값들의 시퀀스처럼 처리하며, 각 SourceCharacter는 유니코드 코드 포인트이다. 표준 ECMAScript 구현체는 소스 텍스트의 정규화(normalization)를 수행하거나, 수행하는 것처럼 동작할 필요가 없다.

조합 문자 시퀀스(combining character sequence)의 구성 요소는 사용자가 전체 시퀀스를 하나의 문자로 인식할 수도 있지만, 각각 개별 유니코드 코드 포인트로 취급된다.

참고

문자열 리터럴, 정규 표현식 리터럴, 템플릿 리터럴, 식별자에서는 어떤 유니코드 코드 포인트도 해당 코드 포인트의 숫자 값을 명시적으로 표현하는 유니코드 이스케이프 시퀀스를 사용하여 나타낼 수 있다. 주석 내에서는 이러한 이스케이프 시퀀스가 주석의 일부로 무시된다.

ECMAScript는 유니코드 이스케이프 시퀀스의 동작에서 Java 프로그래밍 언어와 다르다. 예를 들어, Java 프로그램에서 유니코드 이스케이프 시퀀스 \u000A가 한 줄짜리 주석 내에 나타나면, 이는 줄 종결자(유니코드 코드 포인트 U+000A는 LINE FEED (LF))로 해석되어 다음 코드 포인트는 주석의 일부가 아니다. 마찬가지로, Java 프로그램의 문자열 리터럴 내에 \u000A가 나타나면, 이것도 줄 종결자로 해석되어 문자열 리터럴 내에 허용되지 않는다—문자열 리터럴 값에 LINE FEED (LF)를 포함하려면 \n을 사용해야 한다. ECMAScript 프로그램에서는 주석 내에 등장하는 유니코드 이스케이프 시퀀스가 해석되지 않으므로 주석의 종료에 기여할 수 없다. 또한, ECMAScript 프로그램의 문자열 리터럴 내에 나타나는 유니코드 이스케이프 시퀀스는 항상 리터럴 값에 포함되며, 줄 종결자나 문자열 리터럴을 종료시킬 수 있는 코드 포인트로 해석되지 않는다.

11.1.1 정적 의미: UTF16EncodeCodePoint ( cp )

추상 연산 UTF16EncodeCodePoint는 인자 cp(유니코드 코드 포인트)를 받아 문자열을 반환한다. 호출 시 다음 단계를 수행한다:

  1. Assert: 0 ≤ cp ≤ 0x10FFFF.
  2. cp ≤ 0xFFFF이면, 숫자 값이 cp인 코드 유닛으로 구성된 문자열 값을 반환한다.
  3. cu1을 (cp - 0x10000) / 0x400의 내림(floor)값에 0xD800을 더한 값인 코드 유닛으로 한다.
  4. cu2를 (cp - 0x10000) modulo 0x400의 값에 0xDC00을 더한 값인 코드 유닛으로 한다.
  5. cu1cu2문자열 연결하여 반환한다.

11.1.2 정적 의미: CodePointsToString ( text )

추상 연산 CodePointsToString은 인자 text(유니코드 코드 포인트 시퀀스)를 받아 문자열을 반환한다. text6.1.4에 설명된 대로 문자열 값으로 변환한다. 호출 시 다음 단계를 수행한다:

  1. result를 빈 문자열로 한다.
  2. text의 각 코드 포인트 cp에 대해, 다음을 수행한다:
    1. resultresultUTF16EncodeCodePoint(cp)의 문자열 연결로 설정한다.
  3. result를 반환한다.

11.1.3 정적 의미: UTF16SurrogatePairToCodePoint ( lead, trail )

추상 연산 UTF16SurrogatePairToCodePoint는 인자 lead(코드 유닛), trail(코드 유닛)을 받아 코드 포인트를 반환한다. UTF-16 서러게이트 쌍을 코드 포인트로 변환한다. 호출 시 다음 단계를 수행한다:

  1. Assert: lead리딩 서러게이트이고 trail트레일링 서러게이트이다.
  2. cp를 (lead - 0xD800) × 0x400 + (trail - 0xDC00) + 0x10000으로 한다.
  3. 코드 포인트 cp를 반환한다.

11.1.4 정적 의미: CodePointAt ( string, position )

추상 연산 CodePointAt은 인자 string(문자열), position(음이 아닌 정수)를 받아, Record 타입의 [[CodePoint]](코드 포인트), [[CodeUnitCount]](양의 정수), [[IsUnpairedSurrogate]](불리언) 필드를 가진 결과를 반환한다. string6.1.4에 설명된 대로 UTF-16 인코딩 코드 포인트 시퀀스로 해석하고, position 위치의 코드 유닛에서 시작하는 코드 포인트 하나를 읽는다. 호출 시 다음 단계를 수행한다:

  1. sizestring의 길이로 한다.
  2. Assert: position ≥ 0이고 position < size이다.
  3. firststringposition 인덱스의 코드 유닛으로 한다.
  4. cpfirst의 숫자 값과 동일한 숫자 값을 가지는 코드 포인트로 한다.
  5. first리딩 서러게이트도 아니고 트레일링 서러게이트도 아니면,
    1. 다음 Record를 반환한다: { [[CodePoint]]: cp, [[CodeUnitCount]]: 1, [[IsUnpairedSurrogate]]: false }.
  6. first트레일링 서러게이트이거나 position + 1 = size이면,
    1. 다음 Record를 반환한다: { [[CodePoint]]: cp, [[CodeUnitCount]]: 1, [[IsUnpairedSurrogate]]: true }.
  7. secondstringposition+1 인덱스의 코드 유닛으로 한다.
  8. second트레일링 서러게이트가 아니면,
    1. 다음 Record를 반환한다: { [[CodePoint]]: cp, [[CodeUnitCount]]: 1, [[IsUnpairedSurrogate]]: true }.
  9. cpUTF16SurrogatePairToCodePoint(first, second)로 한다.
  10. 다음 Record를 반환한다: { [[CodePoint]]: cp, [[CodeUnitCount]]: 2, [[IsUnpairedSurrogate]]: false }.

11.1.5 정적 의미: StringToCodePoints ( string )

추상 연산 StringToCodePoints는 인자 string(문자열)을 받아 코드 포인트들의 List를 반환한다. string6.1.4에 설명된 대로 UTF-16 인코딩 유니코드 텍스트로 해석하여 결과로 유니코드 코드 포인트 시퀀스를 반환한다. 호출 시 다음 단계를 수행한다:

  1. codePoints를 새로운 빈 List로 한다.
  2. sizestring의 길이로 한다.
  3. position을 0으로 한다.
  4. position < size인 동안 반복한다:
    1. cpCodePointAt(string, position)으로 한다.
    2. cp.[[CodePoint]]codePoints에 추가한다.
    3. positionposition + cp.[[CodeUnitCount]]로 설정한다.
  5. codePoints를 반환한다.

11.1.6 정적 의미: ParseText ( sourceText, goalSymbol )

추상 연산 ParseText는 인자 sourceText(문자열 또는 유니코드 코드 포인트 시퀀스), goalSymbol(ECMAScript 문법의 비종결 기호(nonterminal))을 받아, 파스 노드(Parse Node) 또는 비어 있지 않은 ListSyntaxError 객체들을 반환한다. 호출 시 다음 단계를 수행한다:

  1. sourceText문자열이면, sourceTextStringToCodePoints(sourceText)로 설정한다.
  2. goalSymbol목표 심볼(goal symbol)로 하여 sourceText를 파싱하고, 파싱 결과에서 조기 에러(early error) 조건을 분석한다. 파싱과 조기 에러 탐지는 구현 정의 방식으로 상호 교차될 수 있다.
  3. 파싱이 성공하고 조기 에러가 발견되지 않았다면, 파싱으로 얻어진 파스 트리의 루트에서 파스 노드(goalSymbol의 인스턴스)를 반환한다.
  4. 그렇지 않으면, 파싱 오류 및/또는 조기 에러를 나타내는 하나 이상의 SyntaxError 객체들의 List를 반환한다. 둘 이상의 파싱 오류 또는 조기 에러가 있는 경우, 오류 객체의 개수와 순서는 구현 정의이지만, 하나 이상은 반드시 포함되어야 한다.
참고 1

특정 위치에 조기 에러가 있고, 이후 위치에 구문 오류가 있는 텍스트를 생각해보자. 파싱 후 조기 에러 탐지 단계를 수행하는 구현체는 구문 오류만 보고하고 조기 에러 탐지를 진행하지 않을 수도 있다. 두 단계를 교차(interleave)하는 구현체는 조기 에러만 보고하고 구문 오류를 찾지 않을 수도 있다. 세 번째 구현체는 두 에러 모두를 보고할 수도 있다. 이 모든 동작은 적합하다.

참고 2

17절도 참고할 것.

11.2 소스 코드의 종류

ECMAScript 코드에는 네 가지 종류가 있다:

참고 1

함수 코드는 일반적으로 함수 정의(15.2), 화살표 함수 정의(15.3), 메서드 정의(15.4), 제너레이터 함수 정의(15.5), 비동기 함수 정의(15.8), 비동기 제너레이터 함수 정의(15.6), 비동기 화살표 함수(15.9)의 본문으로 제공된다. 함수 코드는 Function 생성자(20.2.1.1), GeneratorFunction 생성자(27.3.1.1), AsyncFunction 생성자(27.7.1.1), AsyncGeneratorFunction 생성자(27.4.1.1)의 인자에서도 유도된다.

참고 2

함수 코드에 BindingIdentifier가 포함되는 실질적인 효과는, 엄격 모드 코드(strict mode code)에 대한 조기 에러(Early Errors)가 "use strict" 지시문이 본문에 포함된 함수의 이름이 되는 BindingIdentifier에도 적용된다는 것이다. 이때 바깥쪽 코드는 엄격 모드 코드가 아닐 수 있다.

11.2.1 지시문 프롤로그와 use strict 지시문

지시문 프롤로그ExpressionStatement 들이 StatementListItem 또는 ModuleItem의 처음에 연속적으로 등장하는 가장 긴 시퀀스로, FunctionBody, ScriptBody, ModuleBody의 선두에 위치한다. 이 시퀀스의 각 ExpressionStatement는 오로지 StringLiteral 토큰과 세미콜론으로만 구성되어야 한다. 세미콜론은 명시적으로 존재할 수도 있고, 자동 세미콜론 삽입(12.10)에 의해 삽입될 수도 있다. 지시문 프롤로그는 빈 시퀀스일 수도 있다.

use strict 지시문지시문 프롤로그 내의 ExpressionStatement 중에서, StringLiteral이 정확히 "use strict" 또는 'use strict' 코드 포인트 시퀀스와 일치하는 것이다. use strict 지시문에는 EscapeSequenceLineContinuation가 포함될 수 없다.

지시문 프롤로그에는 둘 이상의 use strict 지시문이 포함될 수 있다. 그러나, 구현체는 이러한 경우 경고를 표시할 수 있다.

참고

지시문 프롤로그ExpressionStatement들은 포함한 프로덕션이 평가될 때 정상적으로 평가된다. 구현체는 지시문 프롤로그 내에 존재하지만 use strict 지시문이 아닌 ExpressionStatement에 대해 구현 정의의 의미를 부여할 수 있다. 적절한 알림 메커니즘이 존재한다면, 구현체는 지시문 프롤로그 내에서 구현에서 정의된 의미가 없는 use strict 지시문이 아닌 ExpressionStatement을 만났을 때 경고를 표시해야 한다.

11.2.2 엄격 모드 코드(Strict Mode Code)

ECMAScript 구문 단위는 제한 없는 모드 또는 엄격 모드 문법 및 의미론(4.3.2)으로 처리될 수 있다. 다음과 같은 상황에서 코드는 엄격 모드 코드로 해석된다:

엄격 모드 코드가 아닌 ECMAScript 코드는 비엄격(non-strict) 코드라고 한다.

11.2.2.1 정적 의미: IsStrict ( node )

추상 연산 IsStrict는 인자 node(파스 노드(Parse Node))를 받아 불리언을 반환한다. 호출 시 다음 단계를 수행한다:

  1. node가 매칭한 소스 텍스트엄격 모드 코드이면 true를 반환하고, 그렇지 않으면 false를 반환한다.

11.2.3 비-ECMAScript 함수

ECMAScript 구현체는 실행 동작이 호스트 정의 실행 코드 형태로 표현되는 함수 익조틱 객체의 평가를 지원할 수 있다. 함수 객체가 ECMAScript 코드 내에서 정의되었는지, 내장 함수인지는 그러한 함수 객체를 호출하거나, 그에 의해 호출되는 ECMAScript 코드의 관점에서는 관찰할 수 없다.

12 ECMAScript 언어: 렉시컬 문법

ECMAScript Script 또는 Module의 소스 텍스트는 먼저 입력 요소들의 시퀀스로 변환된다. 입력 요소란 토큰, 줄 종결자, 주석, 또는 공백이다. 소스 텍스트는 왼쪽에서 오른쪽으로 스캔되며, 가능한 한 가장 긴 코드 포인트 시퀀스를 다음 입력 요소로 반복적으로 선택한다.

렉시컬 입력 요소의 식별은 입력 요소를 소비하는 구문 문법 컨텍스트에 따라 민감하게 달라지는 여러 상황이 있다. 이는 렉시컬 문법에 여러 목표 심볼이 필요함을 의미한다. InputElementHashbangOrRegExp 목표는 Script 또는 Module의 시작 부분에서 사용된다. InputElementRegExpOrTemplateTail 목표는 RegularExpressionLiteral, TemplateMiddle, 또는 TemplateTail이 허용되는 구문 문법 컨텍스트에서 사용된다. InputElementRegExp 목표 심볼RegularExpressionLiteral이 허용되지만 TemplateMiddle 또는 TemplateTail은 허용되지 않는 모든 구문 문법 컨텍스트에서 사용된다. InputElementTemplateTail 목표는 TemplateMiddle 또는 TemplateTail이 허용되고 RegularExpressionLiteral은 허용되지 않는 모든 구문 문법 컨텍스트에서 사용된다. 그 외의 모든 컨텍스트에서는 InputElementDiv가 렉시컬 목표 심볼로 사용된다.

참고

여러 렉시컬 목표를 사용하는 것은 자동 세미콜론 삽입에 영향을 줄 수 있는 렉시컬 모호성이 없도록 보장한다. 예를 들어, 선행하는 나눗셈 또는 나눗셈 할당과 선행하는 RegularExpressionLiteral이 모두 허용되는 구문 문법 컨텍스트는 없다. 이것은 세미콜론 삽입(자세한 내용은 12.10 참고)에 영향을 받지 않는다. 예를 들어 다음과 같은 경우:

a = b
/hi/g.exec(c).map(d);

여기서 LineTerminator 뒤의 첫 번째 공백·주석이 아닌 코드 포인트가 U+002F(SOLIDUS)이고, 구문 컨텍스트가 나눗셈 또는 나눗셈 할당을 허용한다면, 해당 LineTerminator 위치에 세미콜론이 삽입되지 않는다. 즉, 위의 예시는 다음과 동일하게 해석된다:

a = b / hi / g.exec(c).map(d);

구문

InputElementDiv :: WhiteSpace LineTerminator Comment CommonToken DivPunctuator RightBracePunctuator InputElementRegExp :: WhiteSpace LineTerminator Comment CommonToken RightBracePunctuator RegularExpressionLiteral InputElementRegExpOrTemplateTail :: WhiteSpace LineTerminator Comment CommonToken RegularExpressionLiteral TemplateSubstitutionTail InputElementTemplateTail :: WhiteSpace LineTerminator Comment CommonToken DivPunctuator TemplateSubstitutionTail InputElementHashbangOrRegExp :: WhiteSpace LineTerminator Comment CommonToken HashbangComment RegularExpressionLiteral

12.1 유니코드 형식 제어 문자

유니코드 형식 제어 문자(즉, 유니코드 문자 데이터베이스에서 “Cf” 범주에 속하는 문자들, 예: LEFT-TO-RIGHT MARK 또는 RIGHT-TO-LEFT MARK)는 상위 수준의 프로토콜(마크업 언어 등)이 없는 경우에 텍스트 범위의 서식을 제어하는 데 사용되는 제어 코드입니다.

편집과 표시를 용이하게 하기 위해 소스 텍스트에 형식 제어 문자를 허용하는 것이 유용합니다. 모든 형식 제어 문자는 주석, 문자열 리터럴, 템플릿 리터럴, 정규 표현식 리터럴 내에서 사용할 수 있습니다.

U+FEFF(ZERO WIDTH NO-BREAK SPACE)는 주로 텍스트의 시작 부분에서 유니코드임을 표시하고 텍스트의 인코딩과 바이트 순서를 감지할 수 있도록 하는 형식 제어 문자입니다. 이러한 목적을 가진 <ZWNBSP> 문자는 파일을 연결(concatenate)하는 등의 작업 결과로 텍스트의 시작 이후에도 나타날 수 있습니다. ECMAScript 소스 텍스트에서 <ZWNBSP> 코드 포인트는 주석, 문자열 리터럴, 템플릿 리터럴, 정규 표현식 리터럴 외부에서는 공백 문자로 취급됩니다(자세한 내용은 12.2 참고).

12.2 공백(White Space)

공백 코드 포인트는 소스 텍스트의 가독성을 높이고, 토큰(분할 불가능한 렉시컬 단위)들 사이를 구분하는 데 사용되지만, 그 외에는 의미가 없습니다. 공백 코드 포인트는 어떤 두 토큰 사이에도, 입력의 시작이나 끝에도 올 수 있습니다. 공백 코드 포인트는 StringLiteral, RegularExpressionLiteral, Template, TemplateSubstitutionTail 내에도 등장할 수 있으며, 이 경우에는 리터럴 값의 일부를 이루는 의미 있는 코드 포인트로 간주됩니다. 또한 Comment 내에도 등장할 수 있지만, 다른 종류의 토큰 내에는 등장할 수 없습니다.

ECMAScript에서의 공백 코드 포인트는 표 35에 나열되어 있습니다.

표 35: 공백 코드 포인트
코드 포인트 이름 약어
U+0009 CHARACTER TABULATION <TAB>
U+000B LINE TABULATION <VT>
U+000C FORM FEED (FF) <FF>
U+FEFF ZERO WIDTH NO-BREAK SPACE <ZWNBSP>
일반 범주 “Space_Separator”의 임의의 코드 포인트 <USP>
참고 1

U+0020(SPACE) 및 U+00A0(NO-BREAK SPACE) 코드 포인트는 <USP>에 포함됩니다.

참고 2

표 35에 나열된 코드 포인트 외에는, ECMAScript WhiteSpace는 유니코드 “White_Space” 속성을 가진 코드 포인트 중 일반 범주 “Space_Separator”(“Zs”)로 분류되지 않은 모든 코드 포인트를 의도적으로 제외합니다.

구문

WhiteSpace :: <TAB> <VT> <FF> <ZWNBSP> <USP>

12.3 줄 종결자(Line Terminators)

공백 코드 포인트와 마찬가지로, 줄 종결자 코드 포인트도 소스 텍스트의 가독성을 높이고, 토큰(분할 불가능한 렉시컬 단위) 사이를 구분하는 데 사용됩니다. 하지만 공백 코드 포인트와 달리, 줄 종결자는 구문 문법의 동작에 일부 영향을 미칩니다. 일반적으로 줄 종결자는 어떤 두 토큰 사이에도 올 수 있지만, 구문 문법에 의해 금지되는 위치도 일부 있습니다. 줄 종결자는 자동 세미콜론 삽입(12.10) 과정에도 영향을 미칩니다. 줄 종결자는 StringLiteral, Template, TemplateSubstitutionTail 토큰 이외의 어떤 토큰 내에도 올 수 없습니다. <LF>와 <CR> 줄 종결자는 StringLiteral 토큰 내에 LineContinuation의 일부로 나타나는 경우를 제외하고는 올 수 없습니다.

줄 종결자는 MultiLineComment 내에는 올 수 있지만, SingleLineComment 내에는 올 수 없습니다.

줄 종결자는 정규 표현식에서 \s 클래스에 의해 매칭되는 공백 코드 포인트 집합에 포함됩니다.

ECMAScript의 줄 종결자 코드 포인트들은 표 36에 나열되어 있습니다.

표 36: 줄 종결자 코드 포인트
코드 포인트 유니코드 이름 약어
U+000A LINE FEED (LF) <LF>
U+000D CARRIAGE RETURN (CR) <CR>
U+2028 LINE SEPARATOR <LS>
U+2029 PARAGRAPH SEPARATOR <PS>

표 36에 있는 유니코드 코드 포인트만 줄 종결자로 취급됩니다. 다른 줄 바꿈 또는 줄 나눔 유니코드 코드 포인트는 줄 종결자로 취급되지 않으며, 표 35의 조건을 만족하는 경우에만 공백으로 취급됩니다. <CR><LF> 시퀀스는 줄 종결자로 자주 사용됩니다. 이는 줄 번호를 보고(report)할 때 하나의 SourceCharacter로 간주되어야 합니다.

구문

LineTerminator :: <LF> <CR> <LS> <PS> LineTerminatorSequence :: <LF> <CR> [lookahead ≠ <LF>] <LS> <PS> <CR> <LF>

12.4 주석

주석은 한 줄 또는 여러 줄일 수 있습니다. 여러 줄 주석은 중첩될 수 없습니다.

한 줄 주석에는 LineTerminator 코드 포인트를 제외한 임의의 유니코드 코드 포인트가 올 수 있고, 일반적으로 토큰은 항상 가능한 한 가장 길게 취해지므로, 한 줄 주석은 // 마커에서 그 줄의 끝까지의 모든 코드 포인트로 구성됩니다. 그러나, 줄 끝의 LineTerminator는 한 줄 주석의 일부로 간주되지 않습니다. 이는 렉시컬 문법에서 별도로 인식되며, 구문 문법의 입력 요소 스트림의 일부가 됩니다. 이 점은 매우 중요한데, 한 줄 주석의 존재 여부가 자동 세미콜론 삽입 과정에 영향을 주지 않음을 의미합니다(자세한 내용은 12.10 참고).

주석은 공백처럼 동작하며 버려집니다. 단, MultiLineComment에 줄 종결자 코드 포인트가 포함되어 있다면, 해당 전체 주석은 구문 문법 파싱 목적상 LineTerminator로 간주됩니다.

구문

Comment :: MultiLineComment SingleLineComment MultiLineComment :: /* MultiLineCommentCharsopt */ MultiLineCommentChars :: MultiLineNotAsteriskChar MultiLineCommentCharsopt * PostAsteriskCommentCharsopt PostAsteriskCommentChars :: MultiLineNotForwardSlashOrAsteriskChar MultiLineCommentCharsopt * PostAsteriskCommentCharsopt MultiLineNotAsteriskChar :: SourceCharacter *는 제외 MultiLineNotForwardSlashOrAsteriskChar :: SourceCharacter / 또는 *는 제외 SingleLineComment :: // SingleLineCommentCharsopt SingleLineCommentChars :: SingleLineCommentChar SingleLineCommentCharsopt SingleLineCommentChar :: SourceCharacter LineTerminator는 제외

이 절의 일부 생성규칙은 B.1.1 절에서 대체 정의가 주어집니다.

12.5 해시뱅 주석(Hashbang Comments)

해시뱅 주석은 위치에 민감하며, 다른 주석과 마찬가지로 구문 문법의 입력 요소 스트림에서 버려집니다.

구문

HashbangComment :: #! SingleLineCommentCharsopt

12.6 토큰

구문

CommonToken :: IdentifierName PrivateIdentifier Punctuator NumericLiteral StringLiteral Template 참고

DivPunctuator, RegularExpressionLiteral, RightBracePunctuator, TemplateSubstitutionTail 생성규칙들은 CommonToken 생성규칙에 포함되지 않는 추가 토큰을 도출합니다.

12.7 이름과 키워드

IdentifierNameReservedWord는 Unicode Standard Annex #31, Identifier and Pattern Syntax에 명시된 기본 식별자 문법(Default Identifier Syntax)을 약간 수정하여 해석되는 토큰입니다. ReservedWordIdentifierName의 열거된 부분집합입니다. 구문 문법은 IdentifierIdentifierName이면서 ReservedWord가 아닌 것으로 정의합니다. 유니코드 식별자 문법은 유니코드 표준에 명시된 문자 속성을 기반으로 합니다. 최신 버전의 유니코드 표준에서 지정된 범주의 유니코드 코드 포인트는 모든 호환 ECMAScript 구현체에서 해당 범주로 다뤄져야 합니다. ECMAScript 구현체는 이후 유니코드 표준 버전에 정의된 식별자 코드 포인트도 인식할 수 있습니다.

참고 1

이 표준은 다음의 특정 코드 포인트를 추가로 허용합니다: U+0024(DOLLAR SIGN)와 U+005F(LOW LINE)은 IdentifierName 어디에서든 사용할 수 있습니다.

구문

PrivateIdentifier :: # IdentifierName IdentifierName :: IdentifierStart IdentifierName IdentifierPart IdentifierStart :: IdentifierStartChar \ UnicodeEscapeSequence IdentifierPart :: IdentifierPartChar \ UnicodeEscapeSequence IdentifierStartChar :: UnicodeIDStart $ _ IdentifierPartChar :: UnicodeIDContinue $ AsciiLetter :: one of a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z UnicodeIDStart :: 유니코드 속성 “ID_Start”를 가진 임의의 유니코드 코드 포인트 UnicodeIDContinue :: 유니코드 속성 “ID_Continue”를 가진 임의의 유니코드 코드 포인트

비종결 기호 UnicodeEscapeSequence의 정의는 12.9.4에 나와 있습니다.

참고 2

비종결 기호 IdentifierPartUnicodeIDContinue를 통해 _를 도출합니다.

참고 3

유니코드 속성 “ID_Start” 및 “ID_Continue”를 가진 코드 포인트 집합에는 각각 “Other_ID_Start” 및 “Other_ID_Continue” 속성을 가진 코드 포인트도 포함됩니다.

12.7.1 식별자 이름

IdentifierName 내에는 유니코드 이스케이프 시퀀스를 사용할 수 있으며, 이 경우 해당 시퀀스는 UnicodeEscapeSequenceIdentifierCodePoint와 동일한 하나의 유니코드 코드 포인트를 기여합니다. UnicodeEscapeSequence 앞의 \는 코드 포인트에 기여하지 않습니다. UnicodeEscapeSequence는, 그렇지 않으면 유효하지 않은 IdentifierName에 코드 포인트를 기여하는 데 사용할 수 없습니다. 즉, \ UnicodeEscapeSequence 시퀀스를 해당하는 SourceCharacter로 대체해도, 결과가 여전히 동일한 IdentifierName의 정확히 동일한 SourceCharacter 시퀀스가 되어야 합니다. 이 명세 내의 IdentifierName 해석은, 이스케이프 시퀀스가 특정 코드 포인트에 기여했는지 여부와 관계없이 실제 코드 포인트를 기반으로 합니다.

유니코드 표준에 따라 정규적으로 동등한 두 IdentifierName은, 각 UnicodeEscapeSequence를 대체한 후에 코드 포인트의 정확히 동일한 시퀀스로 표현되지 않는 한, 동일하지 않습니다.

12.7.1.1 정적 의미: 조기 에러(Early Errors)

IdentifierStart :: \ UnicodeEscapeSequence IdentifierPart :: \ UnicodeEscapeSequence

12.7.1.2 정적 의미: IdentifierCodePoints

구문-지향 연산 IdentifierCodePoints는 인자를 받지 않으며, 코드 포인트들의 List를 반환합니다. 다음 생성규칙들에 대해 부분적으로 정의됩니다:

IdentifierName :: IdentifierStart
  1. cpIdentifierStartIdentifierCodePoint로 한다.
  2. « cp »를 반환한다.
IdentifierName :: IdentifierName IdentifierPart
  1. cps를 파생된 IdentifierNameIdentifierCodePoints로 한다.
  2. cpIdentifierPartIdentifierCodePoint로 한다.
  3. cps와 « cp »의 리스트 연결을 반환한다.

12.7.1.3 정적 의미: IdentifierCodePoint

구문-지향 연산 IdentifierCodePoint는 인자를 받지 않으며, 코드 포인트를 반환합니다. 다음 생성규칙들에 대해 부분적으로 정의됩니다:

IdentifierStart :: IdentifierStartChar
  1. IdentifierStartChar가 매칭한 코드 포인트를 반환한다.
IdentifierPart :: IdentifierPartChar
  1. IdentifierPartChar가 매칭한 코드 포인트를 반환한다.
UnicodeEscapeSequence :: u Hex4Digits
  1. Hex4Digits의 MV와 동일한 숫자 값을 가지는 코드 포인트를 반환한다.
UnicodeEscapeSequence :: u{ CodePoint }
  1. CodePoint의 MV와 동일한 숫자 값을 가지는 코드 포인트를 반환한다.

12.7.2 키워드와 예약어

키워드IdentifierName과 일치하지만, 구문적으로 사용되는 토큰입니다. 즉, 구문 생성규칙에서 고정폭(fixed width) 글꼴로 문자 그대로 등장합니다. ECMAScript의 키워드에는 if, while, async, await 등 여러 가지가 있습니다.

예약어는 식별자로 사용할 수 없는 IdentifierName입니다. 많은 키워드가 예약어이지만, 일부는 아니기도 하며, 일부는 특정 컨텍스트에서만 예약어입니다. ifwhile은 예약어입니다. await는 async 함수와 모듈 내에서만 예약어입니다. async는 예약어가 아니며, 변수명이나 statement label로 자유롭게 사용할 수 있습니다.

이 명세는 문법 생성규칙과 조기 에러 규칙의 조합으로 어떤 이름이 유효한 식별자인지, 어떤 이름이 예약어인지 명시합니다. 아래 ReservedWord 목록의 모든 토큰(단, awaityield는 제외)은 무조건적으로 예약어입니다. awaityield의 예외는 13.1에서 파라미터화된 구문 생성규칙을 통해 명시됩니다. 마지막으로, 여러 조기 에러 규칙이 유효한 식별자의 집합을 제한합니다. 자세한 내용은 13.1.1, 14.3.1.1, 14.7.5.1, 15.7.1 참고. 요약하면, 식별자 이름에는 다섯 가지 범주가 있습니다:

  • 항상 식별자로 허용되고 키워드가 아닌 것들(Math, window, toString, _ 등)

  • 식별자로 절대 허용되지 않는 것들(아래 ReservedWord 목록 중 awaityield를 제외한 것들)

  • 컨텍스트에 따라 식별자로 허용되는 것들(awaityield)

  • 엄격 모드 코드에서 컨텍스트에 따라 식별자로 허용되지 않는 것들: let, static, implements, interface, package, private, protected, public

  • 항상 식별자로 허용되지만, 특정 구문 생성규칙 내에서 Identifier가 허용되지 않는 위치에서 키워드로도 등장하는 것들(as, async, from, get, meta, of, set, target)

조건부 키워드 또는 컨텍스트 키워드라는 용어는 마지막 세 범주에 속하는 키워드들을 일컫기도 하며, 이들은 어떤 컨텍스트에서는 식별자로, 어떤 컨텍스트에서는 키워드로 사용될 수 있습니다.

구문

ReservedWord :: one of await break case catch class const continue debugger default delete do else enum export extends false finally for function if import in instanceof new null return super switch this throw true try typeof var void while with yield 참고 1

5.1.5에 따라, 문법의 키워드는 특정 SourceCharacter 시퀀스에 문자 그대로 매칭됩니다. 키워드 내의 코드 포인트는 \ UnicodeEscapeSequence로 표현될 수 없습니다.

IdentifierName 내에는 \ UnicodeEscapeSequence를 포함할 수 있지만, els\u{65}와 같이 "else"라는 이름의 변수를 선언할 수는 없습니다. 조기 에러 규칙은 13.1.1에서 예약어와 StringValue가 같은 식별자를 금지합니다.

참고 2

enum은 현재 이 명세에서 키워드로 사용되지 않습니다. 이는 미래의 예약어(future reserved word)로, 향후 언어 확장을 위해 예약되어 있습니다.

마찬가지로 implements, interface, package, private, protected, public엄격 모드 코드 내에서 미래의 예약어입니다.

참고 3

argumentseval은 키워드는 아니지만, 엄격 모드 코드 내에서는 일부 제한을 받습니다. 자세한 내용은 13.1.1, 8.6.4, 15.2.1, 15.5.1, 15.6.1, 15.8.1를 참고하세요.

12.8 구두점(Punctuators)

구문

Punctuator :: OptionalChainingPunctuator OtherPunctuator OptionalChainingPunctuator :: ?. [lookahead ∉ DecimalDigit] OtherPunctuator :: one of { ( ) [ ] . ... ; , < > <= >= == != === !== + - * % ** ++ -- << >> >>> & | ^ ! ~ && || ?? ? : = += -= *= %= **= <<= >>= >>>= &= |= ^= &&= ||= ??= => DivPunctuator :: / /= RightBracePunctuator :: }

12.9 리터럴

12.9.1 Null 리터럴

구문

NullLiteral :: null

12.9.2 불리언 리터럴

구문

BooleanLiteral :: true false

12.9.3 숫자 리터럴

구문

NumericLiteralSeparator :: _ NumericLiteral :: DecimalLiteral DecimalBigIntegerLiteral NonDecimalIntegerLiteral[+Sep] NonDecimalIntegerLiteral[+Sep] BigIntLiteralSuffix LegacyOctalIntegerLiteral DecimalBigIntegerLiteral :: 0 BigIntLiteralSuffix NonZeroDigit DecimalDigits[+Sep]opt BigIntLiteralSuffix NonZeroDigit NumericLiteralSeparator DecimalDigits[+Sep] BigIntLiteralSuffix NonDecimalIntegerLiteral[Sep] :: BinaryIntegerLiteral[?Sep] OctalIntegerLiteral[?Sep] HexIntegerLiteral[?Sep] BigIntLiteralSuffix :: n DecimalLiteral :: DecimalIntegerLiteral . DecimalDigits[+Sep]opt ExponentPart[+Sep]opt . DecimalDigits[+Sep] ExponentPart[+Sep]opt DecimalIntegerLiteral ExponentPart[+Sep]opt DecimalIntegerLiteral :: 0 NonZeroDigit NonZeroDigit NumericLiteralSeparatoropt DecimalDigits[+Sep] NonOctalDecimalIntegerLiteral DecimalDigits[Sep] :: DecimalDigit DecimalDigits[?Sep] DecimalDigit [+Sep] DecimalDigits[+Sep] NumericLiteralSeparator DecimalDigit DecimalDigit :: one of 0 1 2 3 4 5 6 7 8 9 NonZeroDigit :: one of 1 2 3 4 5 6 7 8 9 ExponentPart[Sep] :: ExponentIndicator SignedInteger[?Sep] ExponentIndicator :: one of e E SignedInteger[Sep] :: DecimalDigits[?Sep] + DecimalDigits[?Sep] - DecimalDigits[?Sep] BinaryIntegerLiteral[Sep] :: 0b BinaryDigits[?Sep] 0B BinaryDigits[?Sep] BinaryDigits[Sep] :: BinaryDigit BinaryDigits[?Sep] BinaryDigit [+Sep] BinaryDigits[+Sep] NumericLiteralSeparator BinaryDigit BinaryDigit :: one of 0 1 OctalIntegerLiteral[Sep] :: 0o OctalDigits[?Sep] 0O OctalDigits[?Sep] OctalDigits[Sep] :: OctalDigit OctalDigits[?Sep] OctalDigit [+Sep] OctalDigits[+Sep] NumericLiteralSeparator OctalDigit LegacyOctalIntegerLiteral :: 0 OctalDigit LegacyOctalIntegerLiteral OctalDigit NonOctalDecimalIntegerLiteral :: 0 NonOctalDigit LegacyOctalLikeDecimalIntegerLiteral NonOctalDigit NonOctalDecimalIntegerLiteral DecimalDigit LegacyOctalLikeDecimalIntegerLiteral :: 0 OctalDigit LegacyOctalLikeDecimalIntegerLiteral OctalDigit OctalDigit :: one of 0 1 2 3 4 5 6 7 NonOctalDigit :: one of 8 9 HexIntegerLiteral[Sep] :: 0x HexDigits[?Sep] 0X HexDigits[?Sep] HexDigits[Sep] :: HexDigit HexDigits[?Sep] HexDigit [+Sep] HexDigits[+Sep] NumericLiteralSeparator HexDigit HexDigit :: one of 0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F

SourceCharacterNumericLiteral 바로 뒤에 오면 안 되며, IdentifierStart 또는 DecimalDigit이면 안 된다.

참고

예를 들어: 3in은 오류이며, 3in 두 입력 요소가 아니다.

12.9.3.1 정적 의미: 초기 에러

NumericLiteral :: LegacyOctalIntegerLiteral DecimalIntegerLiteral :: NonOctalDecimalIntegerLiteral
  • 이 생성물에 대해 IsStricttrue인 경우 구문 오류이다.
참고
비엄격 코드에서는 이 구문이 레거시이다.

12.9.3.2 정적 의미: MV

숫자 리터럴은 Number 타입 또는 BigInt 타입의 값을 나타낸다.

12.9.3.3 정적 의미론: NumericValue

구문 지향 연산 NumericValue는 인자를 받지 않으며, Number 또는 BigInt를 반환한다. 다음의 각 생성 규칙에 대해 개별적으로 정의된다:

NumericLiteral :: DecimalLiteral
  1. DecimalLiteral의 MV에 RoundMVResult를 적용한 값을 반환한다.
NumericLiteral :: NonDecimalIntegerLiteral
  1. NonDecimalIntegerLiteral의 MV에 𝔽를 적용한 값을 반환한다.
NumericLiteral :: LegacyOctalIntegerLiteral
  1. LegacyOctalIntegerLiteral의 MV에 𝔽를 적용한 값을 반환한다.
NumericLiteral :: NonDecimalIntegerLiteral BigIntLiteralSuffix
  1. NonDecimalIntegerLiteral의 MV에 대해 BigInt value for를 반환한다.
DecimalBigIntegerLiteral :: 0 BigIntLiteralSuffix
  1. 0을 반환한다.
DecimalBigIntegerLiteral :: NonZeroDigit BigIntLiteralSuffix
  1. NonZeroDigit의 MV에 대해 BigInt value for를 반환한다.
DecimalBigIntegerLiteral :: NonZeroDigit DecimalDigits BigIntLiteralSuffix NonZeroDigit NumericLiteralSeparator DecimalDigits BigIntLiteralSuffix
  1. nDecimalDigits 내에서 NumericLiteralSeparator를 제외한 코드 포인트 개수로 한다.
  2. mv를 (NonZeroDigit의 MV × 10n) + DecimalDigits의 MV로 한다.
  3. (mv)를 반환한다.

12.9.4 문자열 리터럴

참고 1

문자열 리터럴은 작은따옴표 또는 큰따옴표로 감싸진 0개 이상의 유니코드 코드 포인트로 구성된다. 유니코드 코드 포인트는 이스케이프 시퀀스로도 표현될 수 있다. 모든 코드 포인트는 문자열 리터럴에 문자 그대로 나타날 수 있지만, 닫는 따옴표 코드 포인트, U+005C (역슬래시), U+000D (캐리지 리턴), U+000A (줄 바꿈)는 제외된다. 어떤 코드 포인트든 이스케이프 시퀀스 형태로 나타날 수 있다. 문자열 리터럴은 ECMAScript 문자열 값으로 평가된다. 이러한 문자열 값을 생성할 때 유니코드 코드 포인트는 11.1.1에서 정의된 대로 UTF-16으로 인코딩된다. Basic Multilingual Plane에 속한 코드 포인트는 문자열의 단일 코드 유닛 요소로 인코딩된다. 그 외의 모든 코드 포인트는 문자열의 두 코드 유닛 요소로 인코딩된다.

구문

StringLiteral :: " DoubleStringCharactersopt " ' SingleStringCharactersopt ' DoubleStringCharacters :: DoubleStringCharacter DoubleStringCharactersopt SingleStringCharacters :: SingleStringCharacter SingleStringCharactersopt DoubleStringCharacter :: SourceCharacter but not one of " or \ or LineTerminator <LS> <PS> \ EscapeSequence LineContinuation SingleStringCharacter :: SourceCharacter but not one of ' or \ or LineTerminator <LS> <PS> \ EscapeSequence LineContinuation LineContinuation :: \ LineTerminatorSequence EscapeSequence :: CharacterEscapeSequence 0 [lookahead ∉ DecimalDigit] LegacyOctalEscapeSequence NonOctalDecimalEscapeSequence HexEscapeSequence UnicodeEscapeSequence CharacterEscapeSequence :: SingleEscapeCharacter NonEscapeCharacter SingleEscapeCharacter :: one of ' " \ b f n r t v NonEscapeCharacter :: SourceCharacter but not one of EscapeCharacter or LineTerminator EscapeCharacter :: SingleEscapeCharacter DecimalDigit x u LegacyOctalEscapeSequence :: 0 [lookahead ∈ { 8, 9 }] NonZeroOctalDigit [lookahead ∉ OctalDigit] ZeroToThree OctalDigit [lookahead ∉ OctalDigit] FourToSeven OctalDigit ZeroToThree OctalDigit OctalDigit NonZeroOctalDigit :: OctalDigit but not 0 ZeroToThree :: one of 0 1 2 3 FourToSeven :: one of 4 5 6 7 NonOctalDecimalEscapeSequence :: one of 8 9 HexEscapeSequence :: x HexDigit HexDigit UnicodeEscapeSequence :: u Hex4Digits u{ CodePoint } Hex4Digits :: HexDigit HexDigit HexDigit HexDigit

비단말 기호 HexDigit의 정의는 12.9.3에 있다. SourceCharacter11.1에 정의되어 있다.

참고 2

<LF>와 <CR>은 LineContinuation의 일부로서 빈 코드 포인트 시퀀스를 생성하는 경우를 제외하고 문자열 리터럴에 나타날 수 없다. 문자열 리터럴의 문자열 값에 이를 포함시키는 올바른 방법은 \n 또는 \u000A와 같은 이스케이프 시퀀스를 사용하는 것이다.

12.9.4.1 정적 의미론: 초기 에러

EscapeSequence :: LegacyOctalEscapeSequence NonOctalDecimalEscapeSequence
  • IsStrict(이 생성 규칙)이 true이면 구문 에러이다.
참고 1
비엄격 코드에서는 이 구문이 Legacy이다.
참고 2

문자열 리터럴이 Use Strict 지시문 앞에 올 수 있으며, 이 경우 둘러싸는 코드가 엄격 모드가 된다. 구현체는 이러한 리터럴에 대해 위 규칙을 적용해야 한다. 예를 들어, 다음 소스 텍스트는 구문 에러를 포함한다:

function invalid() { "\7"; "use strict"; }

12.9.4.2 정적 의미론: SV

구문 지향 연산 SV는 인자를 받지 않으며, 문자열을 반환한다.

문자열 리터럴은 String 타입의 값을 의미한다. SV는 문자열 리터럴의 다양한 부분에 재귀적으로 적용되어 문자열 값을 생성한다. 이 과정의 일부로, 문자열 리터럴 내의 일부 유니코드 코드 포인트는 아래 또는 12.9.3에서 설명한 대로 수학적 값을 갖는 것으로 해석된다.

표 37: 문자열 단일 문자 이스케이프 시퀀스
이스케이프 시퀀스 코드 유닛 값 유니코드 문자 이름 기호
\b 0x0008 백스페이스(BACKSPACE) <BS>
\t 0x0009 문자 탭(CHARACTER TABULATION) <HT>
\n 0x000A 줄 바꿈(LINE FEED, LF) <LF>
\v 0x000B 수직 탭(LINE TABULATION) <VT>
\f 0x000C 폼 피드(FORM FEED, FF) <FF>
\r 0x000D 캐리지 리턴(CARRIAGE RETURN, CR) <CR>
\" 0x0022 큰따옴표(QUOTATION MARK) "
\' 0x0027 작은따옴표(APOSTROPHE) '
\\ 0x005C 역슬래시(REVERSE SOLIDUS) \

12.9.4.3 정적 의미론: MV

12.9.5 정규 표현식 리터럴

노트 1

정규 표현식 리터럴은 평가될 때마다 RegExp 객체로 변환되는 입력 요소입니다 (22.2 참조). 프로그램 내의 두 정규 표현식 리터럴은, 두 리터럴의 내용이 동일하더라도 서로 ===로 비교될 때 같지 않은 정규 표현식 객체로 평가됩니다. RegExp 객체는 new RegExp 또는 RegExp 생성자를 함수로 호출하여 런타임에 생성할 수도 있습니다 (22.2.4 참조).

아래의 생성 규칙은 정규 표현식 리터럴의 구문을 설명하며, 입력 요소 스캐너가 정규 표현식 리터럴의 끝을 찾을 때 사용됩니다. RegularExpressionBodyRegularExpressionFlags를 구성하는 소스 텍스트는 이후 더 엄격한 ECMAScript 정규 표현식 문법을 사용하여 다시 파싱됩니다 (22.2.1).

구현체는 22.2.1에 정의된 ECMAScript 정규 표현식 문법을 확장할 수 있지만, 아래에 정의된 RegularExpressionBodyRegularExpressionFlags 생성 규칙 또는 이 생성 규칙들이 사용하는 생성 규칙은 확장할 수 없습니다.

구문

RegularExpressionLiteral :: / RegularExpressionBody / RegularExpressionFlags RegularExpressionBody :: RegularExpressionFirstChar RegularExpressionChars RegularExpressionChars :: [empty] RegularExpressionChars RegularExpressionChar RegularExpressionFirstChar :: RegularExpressionNonTerminator 단, * 또는 \ 또는 / 또는 [ 중 하나가 아니어야 함 RegularExpressionBackslashSequence RegularExpressionClass RegularExpressionChar :: RegularExpressionNonTerminator 단, \ 또는 / 또는 [ 중 하나가 아니어야 함 RegularExpressionBackslashSequence RegularExpressionClass RegularExpressionBackslashSequence :: \ RegularExpressionNonTerminator RegularExpressionNonTerminator :: SourceCharacter LineTerminator가 아니어야 함 RegularExpressionClass :: [ RegularExpressionClassChars ] RegularExpressionClassChars :: [empty] RegularExpressionClassChars RegularExpressionClassChar RegularExpressionClassChar :: RegularExpressionNonTerminator 단, ] 또는 \ 중 하나가 아니어야 함 RegularExpressionBackslashSequence RegularExpressionFlags :: [empty] RegularExpressionFlags IdentifierPartChar 노트 2

정규 표현식 리터럴은 비어 있을 수 없습니다; 빈 정규 표현식 리터럴을 나타내는 대신, 코드 유닛 시퀀스 //는 단일 행 주석을 시작합니다. 빈 정규 표현식을 지정하려면 /(?:)/을 사용하세요.

12.9.5.1 정적 의미론: BodyText

구문 지시 연산 BodyText는 인수를 받지 않으며 소스 텍스트를 반환합니다. 다음 생성 규칙에 대해 개별적으로 정의됩니다:

RegularExpressionLiteral :: / RegularExpressionBody / RegularExpressionFlags
  1. RegularExpressionBody로 인식된 소스 텍스트를 반환한다.

12.9.5.2 정적 의미론: FlagText

구문 지시 연산 FlagText는 인수를 받지 않으며 소스 텍스트를 반환합니다. 다음 생성 규칙에 대해 개별적으로 정의됩니다:

RegularExpressionLiteral :: / RegularExpressionBody / RegularExpressionFlags
  1. RegularExpressionFlags로 인식된 소스 텍스트를 반환한다.

12.9.6 템플릿 리터럴 렉시컬 구성 요소

구문

Template :: NoSubstitutionTemplate TemplateHead NoSubstitutionTemplate :: ` TemplateCharactersopt ` TemplateHead :: ` TemplateCharactersopt ${ TemplateSubstitutionTail :: TemplateMiddle TemplateTail TemplateMiddle :: } TemplateCharactersopt ${ TemplateTail :: } TemplateCharactersopt ` TemplateCharacters :: TemplateCharacter TemplateCharactersopt TemplateCharacter :: $ [lookahead ≠ {] \ TemplateEscapeSequence \ NotEscapeSequence LineContinuation LineTerminatorSequence SourceCharacter 단, ` 또는 \ 또는 $ 또는 LineTerminator 중 하나가 아니어야 함 TemplateEscapeSequence :: CharacterEscapeSequence 0 [lookahead ∉ DecimalDigit] HexEscapeSequence UnicodeEscapeSequence NotEscapeSequence :: 0 DecimalDigit DecimalDigit 단, 0이 아니어야 함 x [lookahead ∉ HexDigit] x HexDigit [lookahead ∉ HexDigit] u [lookahead ∉ HexDigit] [lookahead ≠ {] u HexDigit [lookahead ∉ HexDigit] u HexDigit HexDigit [lookahead ∉ HexDigit] u HexDigit HexDigit HexDigit [lookahead ∉ HexDigit] u { [lookahead ∉ HexDigit] u { NotCodePoint [lookahead ∉ HexDigit] u { CodePoint [lookahead ∉ HexDigit] [lookahead ≠ }] NotCodePoint :: HexDigits[~Sep] 단, HexDigits의 MV가 0x10FFFF보다 커야 함 CodePoint :: HexDigits[~Sep] 단, HexDigits의 MV가 0x10FFFF 이하여야 함 노트

TemplateSubstitutionTailInputElementTemplateTail 대안 렉시컬 목표에서 사용됩니다.

12.9.6.1 정적 의미론: TV

구문 지시 연산 TV는 인수를 받지 않으며 String 또는 undefined를 반환합니다. 템플릿 리터럴 구성 요소는 TV에 의해 String 타입 값으로 해석됩니다. TV는 템플릿 객체의 인덱스드 구성 요소(일상적으로 템플릿 값)를 구성하는 데 사용됩니다. TV에서 이스케이프 시퀀스는 해당 이스케이프 시퀀스가 나타내는 유니코드 코드 포인트의 UTF-16 코드 유닛(들)로 대체됩니다.

12.9.6.2 정적 의미론: TRV

구문 지시 연산 TRV는 인수를 받지 않으며 String을 반환합니다. 템플릿 리터럴 구성 요소는 TRV에 의해 String 타입 값으로 해석됩니다. TRV는 템플릿 객체의 원시(raw) 구성 요소(일상적으로 템플릿 원시 값)를 구성하는 데 사용됩니다. TRV는 TV와 유사하지만, TRV에서는 이스케이프 시퀀스가 리터럴에 나타난 그대로 해석된다는 점이 다릅니다.

노트

TVLineContinuation의 코드 유닛을 제외하지만, TRV는 이를 포함합니다. <CR><LF>와 <CR> LineTerminatorSequenceTV와 TRV 모두에서 <LF>로 정규화됩니다. <CR> 또는 <CR><LF> 시퀀스를 포함하려면 TemplateEscapeSequence를 명시적으로 사용해야 합니다.

12.10 자동 세미콜론 삽입

대부분의 ECMAScript 문장과 선언은 세미콜론으로 끝나야 합니다. 이러한 세미콜론은 소스 텍스트에 항상 명시적으로 나타낼 수 있습니다. 하지만 편의를 위해, 특정 상황에서는 이러한 세미콜론을 소스 텍스트에서 생략할 수 있습니다. 이러한 상황에서는 세미콜론이 자동으로 소스 코드 토큰 스트림에 삽입된다고 설명합니다.

12.10.1 자동 세미콜론 삽입 규칙

다음 규칙에서 “토큰(token)”은 목표 심볼로 현재 렉시컬 분석에서 인식된 실제 렉시컬 토큰을 의미하며, 이는 12절에 설명되어 있습니다.

세미콜론 삽입의 기본 규칙은 세 가지가 있습니다:

  1. 소스 텍스트를 왼쪽에서 오른쪽으로 파싱할 때, 어떤 생산 규칙에도 허용되지 않는 토큰(offending token이라 함)을 만나면, 다음 조건 중 하나라도 참이면 그 토큰 앞에 세미콜론이 자동으로 삽입됩니다:

    • offending token이 이전 토큰과 하나 이상의 LineTerminator로 구분되어 있는 경우.
    • offending token이 }인 경우.
    • 이전 토큰이 )이고, 삽입된 세미콜론이 do-while 문(14.7.2)의 종료 세미콜론으로 파싱되는 경우.
  2. 소스 텍스트를 왼쪽에서 오른쪽으로 파싱할 때, 토큰 입력 스트림의 끝에 도달하고 파서가 입력 토큰 스트림을 목표 비단말의 단일 인스턴스로 파싱할 수 없는 경우, 입력 스트림의 끝에 세미콜론이 자동으로 삽입됩니다.
  3. 소스 텍스트를 왼쪽에서 오른쪽으로 파싱할 때, 어떤 토큰이 문법의 어떤 생산 규칙에 의해 허용되지만, 그 생산 규칙이 제한된 생산(restricted production)이고 그 토큰이 “[no LineTerminator here]” 주석 바로 다음에 오는 터미널 또는 비단말의 첫 번째 토큰(따라서 restricted token이라 함)이며, 그 restricted token이 이전 토큰과 하나 이상의 LineTerminator로 구분되어 있다면, 해당 restricted token 앞에 세미콜론이 자동으로 삽입됩니다.

하지만, 앞선 규칙들에 대한 추가적인 우선 조건이 있습니다: 세미콜론이 자동으로 삽입되어 빈 문장(empty statement)이 되거나, for문 헤더의 두 세미콜론 중 하나가 되면, 세미콜론은 절대 자동 삽입되지 않습니다(14.7.4 참조).

노트

다음은 문법에서 유일하게 제한된 생산(restricted production)입니다:

UpdateExpression[Yield, Await] : LeftHandSideExpression[?Yield, ?Await] [no LineTerminator here] ++ LeftHandSideExpression[?Yield, ?Await] [no LineTerminator here] -- ContinueStatement[Yield, Await] : continue ; continue [no LineTerminator here] LabelIdentifier[?Yield, ?Await] ; BreakStatement[Yield, Await] : break ; break [no LineTerminator here] LabelIdentifier[?Yield, ?Await] ; ReturnStatement[Yield, Await] : return ; return [no LineTerminator here] Expression[+In, ?Yield, ?Await] ; ThrowStatement[Yield, Await] : throw [no LineTerminator here] Expression[+In, ?Yield, ?Await] ; YieldExpression[In, Await] : yield yield [no LineTerminator here] AssignmentExpression[?In, +Yield, ?Await] yield [no LineTerminator here] * AssignmentExpression[?In, +Yield, ?Await] ArrowFunction[In, Yield, Await] : ArrowParameters[?Yield, ?Await] [no LineTerminator here] => ConciseBody[?In] AsyncFunctionDeclaration[Yield, Await, Default] : async [no LineTerminator here] function BindingIdentifier[?Yield, ?Await] ( FormalParameters[~Yield, +Await] ) { AsyncFunctionBody } [+Default] async [no LineTerminator here] function ( FormalParameters[~Yield, +Await] ) { AsyncFunctionBody } AsyncFunctionExpression : async [no LineTerminator here] function BindingIdentifier[~Yield, +Await]opt ( FormalParameters[~Yield, +Await] ) { AsyncFunctionBody } AsyncMethod[Yield, Await] : async [no LineTerminator here] ClassElementName[?Yield, ?Await] ( UniqueFormalParameters[~Yield, +Await] ) { AsyncFunctionBody } AsyncGeneratorDeclaration[Yield, Await, Default] : async [no LineTerminator here] function * BindingIdentifier[?Yield, ?Await] ( FormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } [+Default] async [no LineTerminator here] function * ( FormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } AsyncGeneratorExpression : async [no LineTerminator here] function * BindingIdentifier[+Yield, +Await]opt ( FormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } AsyncGeneratorMethod[Yield, Await] : async [no LineTerminator here] * ClassElementName[?Yield, ?Await] ( UniqueFormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } AsyncArrowFunction[In, Yield, Await] : async [no LineTerminator here] AsyncArrowBindingIdentifier[?Yield] [no LineTerminator here] => AsyncConciseBody[?In] CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await] [no LineTerminator here] => AsyncConciseBody[?In] AsyncArrowHead : async [no LineTerminator here] ArrowFormalParameters[~Yield, +Await]

이러한 제한된 생산의 실질적 효과는 다음과 같습니다:

  • ++ 또는 -- 토큰이 후위 연산자로 처리되는 위치에서, 그 앞에 하나 이상의 LineTerminator가 있으면, ++ 또는 -- 앞에 세미콜론이 자동 삽입됩니다.
  • continue, break, return, throw, yield 토큰이 등장하고, 그 다음 토큰 앞에 LineTerminator가 있으면, 해당 토큰 뒤에 세미콜론이 자동 삽입됩니다.
  • 화살표 함수(arrow function) 파라미터 뒤에 LineTerminator가 오고, 그 뒤에 => 토큰이 오면, 세미콜론이 자동 삽입되고 해당 구두점은 구문 오류를 발생시킵니다.
  • async 토큰 뒤에 LineTerminator가 오고, 그 다음에 function 또는 IdentifierName 또는 ( 토큰이 오면, 세미콜론이 자동 삽입되고 async는 다음 토큰들과 같은 식이나 클래스 요소의 일부로 처리되지 않습니다.
  • async 토큰 뒤에 LineTerminator가 오고, 그 다음에 * 토큰이 오면, 세미콜론이 자동 삽입되고 해당 구두점은 구문 오류를 발생시킵니다.

이로 인해 ECMAScript 프로그래머에게 실질적으로 권장되는 사항은 다음과 같습니다:

  • 후위 ++ 또는 -- 연산자는 피연산자와 같은 줄에 있어야 합니다.
  • Expressionreturn 또는 throw문에 있거나, AssignmentExpressionyield 표현식에 있을 때는, 그 시작이 return, throw, yield 토큰과 같은 줄에 있어야 합니다.
  • LabelIdentifierbreak 또는 continue 문에 있을 때는, break 또는 continue 토큰과 같은 줄에 있어야 합니다.
  • 화살표 함수의 파라미터 끝과 =>는 같은 줄에 있어야 합니다.
  • 비동기 함수나 메서드 앞의 async 토큰은 바로 뒤 토큰과 같은 줄에 있어야 합니다.

12.10.2 자동 세미콜론 삽입의 예시

이 절은 규범적인 내용이 아닙니다.

다음 소스는

{ 1 2 } 3

자동 세미콜론 삽입 규칙이 있더라도 ECMAScript 문법에서 유효한 문장이 아닙니다. 반면, 다음 소스

{ 1
2 } 3

도 ECMAScript 문법상 유효한 문장은 아니지만, 자동 세미콜론 삽입에 의해 다음과 같이 변환됩니다:

{ 1
;2 ;} 3;

이것은 유효한 ECMAScript 문장입니다.

다음 소스

for (a; b
)

는 유효한 ECMAScript 문장이 아니며, 자동 세미콜론 삽입에 의해 변경되지 않습니다. 그 이유는 for 문 헤더에 필요한 세미콜론이기 때문입니다. 자동 세미콜론 삽입은 for 문 헤더의 두 세미콜론 중 하나를 절대 삽입하지 않습니다.

다음 소스

return
a + b

는 자동 세미콜론 삽입에 의해 다음과 같이 변환됩니다:

return;
a + b;
노트 1

a + b 식은 return 문에 의해 반환되는 값으로 처리되지 않습니다. 그 이유는 LineTerminatorreturn 토큰과 그 뒤 토큰 사이에 있기 때문입니다.

다음 소스

a = b
++c

는 자동 세미콜론 삽입에 의해 다음과 같이 변환됩니다:

a = b;
++c;
노트 2

++ 토큰은 변수 b에 적용되는 후위 연산자로 처리되지 않습니다. 그 이유는 LineTerminatorb++ 사이에 있기 때문입니다.

다음 소스

if (a > b)
else c = d

는 유효한 ECMAScript 문장이 아니며, else 토큰 앞에 자동 세미콜론 삽입으로 변경되지 않습니다. 그 이유는 그 경우 자동 삽입된 세미콜론이 빈 문장(empty statement)이 되기 때문입니다.

다음 소스

a = b + c
(d + e).print()

는 자동 세미콜론 삽입에 의해 변환되지 않습니다. 그 이유는 두 번째 줄이 괄호로 시작하는 식이기 때문에, 전체가 함수 호출의 인수 목록으로 해석될 수 있기 때문입니다:

a = b + c(d + e).print()

대입문이 왼쪽 괄호로 시작해야 하는 상황에서는, 자동 세미콜론 삽입에 의존하기보다는 명시적으로 이전 문장의 끝에 세미콜론을 추가하는 것이 좋습니다.

12.10.3 자동 세미콜론 삽입의 흥미로운 사례

이 절은 규범적인 내용이 아닙니다.

ECMAScript 프로그램은 자동 세미콜론 삽입에 의존해 아주 적은 세미콜론만으로 작성될 수도 있습니다. 위에서 설명한 대로, 세미콜론은 모든 줄 바꿈마다 삽입되지 않으며, 자동 세미콜론 삽입은 여러 토큰이 줄 바꿈을 가로지르는지에 따라 달라질 수 있습니다.

ECMAScript에 새로운 문법 기능이 추가됨에 따라, 자동 세미콜론 삽입에 의존하는 라인 앞에서 문법 생산이 달라지는 추가 문법 생산이 추가될 수 있습니다.

이 절에서는, 세미콜론이 삽입될 수도 있고 아닐 수도 있는 위치(즉, 앞선 소스 텍스트에 따라 달라지는 위치)를 자동 세미콜론 삽입의 흥미로운 사례로 간주합니다. 이 절의 나머지 부분에서는 이 버전의 ECMAScript에서 자동 세미콜론 삽입의 여러 흥미로운 사례를 설명합니다.

12.10.3.1 Statement List에서의 자동 세미콜론 삽입의 흥미로운 사례

StatementList에서, 많은 StatementListItem은 세미콜론으로 끝나며, 자동 세미콜론 삽입을 통해 생략할 수 있습니다. 위 규칙의 결과로, 표현식이 끝나는 줄의 끝에서 다음 줄이 아래 항목 중 하나로 시작한다면, 세미콜론이 필요합니다:

  • 여는 괄호((). 세미콜론이 없으면 두 줄이 CallExpression으로 해석됩니다.
  • 여는 대괄호([). 세미콜론이 없으면 두 줄이 속성 접근으로 해석되며, ArrayLiteral 또는 ArrayAssignmentPattern로 해석되지 않습니다.
  • 템플릿 리터럴(`). 세미콜론이 없으면 두 줄이 태그드 템플릿(13.3.11)으로 해석되며, 앞의 표현식이 MemberExpression이 됩니다.
  • 단항 + 또는 -. 세미콜론이 없으면 두 줄이 해당 이항 연산자의 사용으로 해석됩니다.
  • 정규 표현식 리터럴. 세미콜론이 없으면 두 줄이 / MultiplicativeOperator로 해석될 수 있으며(예를 들어 정규식에 플래그가 있을 때).

12.10.3.2 자동 세미콜론 삽입과 “[no LineTerminator here]” 사례

이 절은 규범적인 내용이 아닙니다.

ECMAScript에는 “[no LineTerminator here]”를 포함하는 문법 생산이 있습니다. 이러한 생산은 때때로 문법에서 피연산자를 선택적으로 허용하기 위한 수단으로 쓰입니다. 이러한 위치에 LineTerminator를 도입하면, 선택적 피연산자가 없는 문법 생산을 사용하게 되어 문법 생산이 바뀝니다.

이 절의 나머지 부분에서는 이 버전의 ECMAScript에서 “[no LineTerminator here]”를 사용하는 여러 생산을 설명합니다.

12.10.3.2.1 선택적 피연산자와 “[no LineTerminator here]”가 있는 문법 생산 목록

13 ECMAScript 언어: 표현식

13.1 식별자

구문

IdentifierReference[Yield, Await] : Identifier [~Yield] yield [~Await] await BindingIdentifier[Yield, Await] : Identifier yield await LabelIdentifier[Yield, Await] : Identifier [~Yield] yield [~Await] await Identifier : IdentifierName but not ReservedWord 참고

yieldawait는 문법에서 BindingIdentifier로 허용되며, 아래 정적 의미에서 금지되어, 다음과 같은 경우 자동 세미콜론 삽입을 방지한다.

let
await 0;

13.1.1 정적 의미: 초기 에러

BindingIdentifier : Identifier IdentifierReference : yield BindingIdentifier : yield LabelIdentifier : yield
  • IsStrict(이 생성규칙)이 true이면 구문 에러이다.
IdentifierReference : await BindingIdentifier : await LabelIdentifier : await BindingIdentifier[Yield, Await] : yield
  • 이 생성규칙이 [Yield] 매개변수를 가지면 구문 에러이다.
BindingIdentifier[Yield, Await] : await
  • 이 생성규칙이 [Await] 매개변수를 가지면 구문 에러이다.
IdentifierReference[Yield, Await] : Identifier BindingIdentifier[Yield, Await] : Identifier LabelIdentifier[Yield, Await] : Identifier
  • 이 생성규칙이 [Yield] 매개변수를 가지고, IdentifierStringValue"yield"이면 구문 에러이다.
  • 이 생성규칙이 [Await] 매개변수를 가지고, IdentifierStringValue"await"이면 구문 에러이다.
Identifier : IdentifierName but not ReservedWord 참고

IdentifierNameStringValueIdentifierName의 모든 유니코드 이스케이프 시퀀스를 정규화하므로, IdentifierReservedWord의 코드 포인트 시퀀스가 동일하도록 이스케이프를 사용할 수 없다.

13.1.2 정적 의미: StringValue

구문-지시 연산 StringValue는 인자를 받지 않으며 문자열을 반환한다. 다음 생성규칙에 대해 분할적으로 정의된다:

IdentifierName :: IdentifierStart IdentifierName IdentifierPart
  1. idTextUnescapedIdentifierNameIdentifierCodePoints로 한다.
  2. CodePointsToString(idTextUnescaped)를 반환한다.
IdentifierReference : yield BindingIdentifier : yield LabelIdentifier : yield
  1. "yield"를 반환한다.
IdentifierReference : await BindingIdentifier : await LabelIdentifier : await
  1. "await"를 반환한다.
Identifier : IdentifierName but not ReservedWord
  1. IdentifierNameStringValue를 반환한다.
PrivateIdentifier :: # IdentifierName
  1. 0x0023(샾, #)과 IdentifierNameStringValue문자열 결합하여 반환한다.
ModuleExportName : StringLiteral
  1. StringLiteralSV를 반환한다.

13.1.3 런타임 의미: 평가

IdentifierReference : Identifier
  1. IdentifierStringValueResolveBinding을(를) 호출한 결과를 반환한다.
IdentifierReference : yield
  1. ResolveBinding("yield")의 결과를 반환한다.
IdentifierReference : await
  1. ResolveBinding("await")의 결과를 반환한다.
참고 1

IdentifierReference의 평가 결과는 항상 Reference 타입의 값이다.

참고 2

비엄격 코드에서는, 키워드 yield를 식별자로 사용할 수 있다. IdentifierReference의 평가 결과는 yield의 바인딩을 Identifier로서 해석한 것과 같이 된다. 초기 에러 제한은 이러한 평가가 비엄격 코드에서만 발생할 수 있도록 보장한다.

13.2 기본 표현식

구문

PrimaryExpression[Yield, Await] : this IdentifierReference[?Yield, ?Await] Literal ArrayLiteral[?Yield, ?Await] ObjectLiteral[?Yield, ?Await] FunctionExpression ClassExpression[?Yield, ?Await] GeneratorExpression AsyncFunctionExpression AsyncGeneratorExpression RegularExpressionLiteral TemplateLiteral[?Yield, ?Await, ~Tagged] CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await] CoverParenthesizedExpressionAndArrowParameterList[Yield, Await] : ( Expression[+In, ?Yield, ?Await] ) ( Expression[+In, ?Yield, ?Await] , ) ( ) ( ... BindingIdentifier[?Yield, ?Await] ) ( ... BindingPattern[?Yield, ?Await] ) ( Expression[+In, ?Yield, ?Await] , ... BindingIdentifier[?Yield, ?Await] ) ( Expression[+In, ?Yield, ?Await] , ... BindingPattern[?Yield, ?Await] )

보조 구문

다음 생성규칙의 인스턴스를 처리할 때
PrimaryExpression[Yield, Await] : CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await]
CoverParenthesizedExpressionAndArrowParameterList의 해석은 다음 문법을 사용하여 보정된다:

ParenthesizedExpression[Yield, Await] : ( Expression[+In, ?Yield, ?Await] )

13.2.1 this 키워드

13.2.1.1 런타임 의미: 평가

PrimaryExpression : this
  1. ResolveThisBinding()를 반환한다.

13.2.2 식별자 참조

IdentifierReference에 대해서는 13.1를 참조하라.

13.2.3 리터럴

구문

Literal : NullLiteral BooleanLiteral NumericLiteral StringLiteral

13.2.3.1 런타임 의미: 평가

Literal : NullLiteral
  1. null을 반환한다.
Literal : BooleanLiteral
  1. BooleanLiteral이 토큰 false이면 false를 반환한다.
  2. BooleanLiteral이 토큰 true이면 true를 반환한다.
Literal : NumericLiteral
  1. NumericLiteralNumericValue12.9.3에 정의된 대로 반환한다.
Literal : StringLiteral
  1. StringLiteralSV12.9.4.2에 정의된 대로 반환한다.

13.2.4 배열 이니셜라이저

참고

ArrayLiteral은 대괄호로 둘러싸인, 0개 이상의 각 요소가 배열의 원소를 나타내는 표현식으로 이루어진 리스트를 사용하여 배열(Array)의 초기화를 기술하는 표현식이다. 요소들은 반드시 리터럴일 필요는 없으며, 배열 이니셜라이저가 평가될 때마다 각각 평가된다.

배열 요소는 요소 리스트의 시작, 중간, 끝 모두에서 생략될 수 있다. 요소 리스트에서 콤마가 AssignmentExpression 앞에 오지 않는 경우(즉, 시작이거나 또 다른 콤마 뒤), 해당 빠진 배열 요소는 배열의 길이에 기여하며 이후 요소의 인덱스를 증가시킨다. 생략된 배열 요소는 정의되지 않는다. 배열의 끝에 요소가 생략된 경우, 해당 요소는 배열의 길이에 기여하지 않는다.

구문

ArrayLiteral[Yield, Await] : [ Elisionopt ] [ ElementList[?Yield, ?Await] ] [ ElementList[?Yield, ?Await] , Elisionopt ] ElementList[Yield, Await] : Elisionopt AssignmentExpression[+In, ?Yield, ?Await] Elisionopt SpreadElement[?Yield, ?Await] ElementList[?Yield, ?Await] , Elisionopt AssignmentExpression[+In, ?Yield, ?Await] ElementList[?Yield, ?Await] , Elisionopt SpreadElement[?Yield, ?Await] Elision : , Elision , SpreadElement[Yield, Await] : ... AssignmentExpression[+In, ?Yield, ?Await]

13.2.4.1 런타임 의미: ArrayAccumulation

구문-지시 연산 ArrayAccumulation은 인수 array(배열)와 nextIndex(정수)를 받아, 정상 완료(normal completion)정수를 반환하거나, 비정상 완료(abrupt completion)를 반환한다. 다음 생성규칙에 따라 구체적으로 정의된다:

Elision : ,
  1. lennextIndex + 1로 한다.
  2. Set(array, "length", 𝔽(len), true)를 수행한다.
  3. 참고: 위 단계에서 len이 232 - 1을 초과하면 예외가 발생한다.
  4. len을 반환한다.
Elision : Elision ,
  1. ArrayAccumulationElision에 대해 array와 (nextIndex + 1)을 인수로 호출한 결과를 반환한다.
ElementList : Elisionopt AssignmentExpression
  1. Elision이 존재하면,
    1. nextIndex를 ? ArrayAccumulationElision에 대해 arraynextIndex를 인수로 호출한 결과로 설정한다.
  2. initResult를 ? EvaluationAssignmentExpression에 대해 호출한 결과로 한다.
  3. initValue를 ? GetValue(initResult)로 한다.
  4. CreateDataPropertyOrThrow(array, ! ToString(𝔽(nextIndex)), initValue)를 수행한다.
  5. nextIndex + 1을 반환한다.
ElementList : Elisionopt SpreadElement
  1. Elision이 존재하면,
    1. nextIndex를 ? ArrayAccumulationElision에 대해 arraynextIndex를 인수로 호출한 결과로 설정한다.
  2. ArrayAccumulationSpreadElement에 대해 arraynextIndex를 인수로 호출한 결과를 반환한다.
ElementList : ElementList , Elisionopt AssignmentExpression
  1. nextIndex를 ? ArrayAccumulationElementList에 대해 arraynextIndex를 인수로 호출한 결과로 설정한다.
  2. Elision이 존재하면,
    1. nextIndex를 ? ArrayAccumulationElision에 대해 arraynextIndex를 인수로 호출한 결과로 설정한다.
  3. initResult를 ? EvaluationAssignmentExpression에 대해 호출한 결과로 한다.
  4. initValue를 ? GetValue(initResult)로 한다.
  5. CreateDataPropertyOrThrow(array, ! ToString(𝔽(nextIndex)), initValue)를 수행한다.
  6. nextIndex + 1을 반환한다.
ElementList : ElementList , Elisionopt SpreadElement
  1. nextIndex를 ? ArrayAccumulationElementList에 대해 arraynextIndex를 인수로 호출한 결과로 설정한다.
  2. Elision이 존재하면,
    1. nextIndex를 ? ArrayAccumulationElision에 대해 arraynextIndex를 인수로 호출한 결과로 설정한다.
  3. ArrayAccumulationSpreadElement에 대해 arraynextIndex를 인수로 호출한 결과를 반환한다.
SpreadElement : ... AssignmentExpression
  1. spreadRef를 ? EvaluationAssignmentExpression에 대해 호출한 결과로 한다.
  2. spreadObj를 ? GetValue(spreadRef)로 한다.
  3. iteratorRecord를 ? GetIterator(spreadObj, sync)로 한다.
  4. 반복한다,
    1. next를 ? IteratorStepValue(iteratorRecord)로 한다.
    2. nextdone이면 nextIndex를 반환한다.
    3. CreateDataPropertyOrThrow(array, ! ToString(𝔽(nextIndex)), next)를 수행한다.
    4. nextIndexnextIndex + 1로 설정한다.
참고

CreateDataPropertyOrThrow는 표준 내장 Array 프로토타입 객체[[Set]]을 이용한 새로운 자체 속성 생성을 막는 방식으로 수정된 경우에도, 배열에 자체 속성이 정의되도록 보장하기 위해 사용된다.

13.2.4.2 런타임 의미: 평가

ArrayLiteral : [ Elisionopt ]
  1. array를 ! ArrayCreate(0)로 한다.
  2. Elision이 존재하면,
    1. ArrayAccumulationElision에 대해 array와 0을 인수로 호출하여 수행한다.
  3. array를 반환한다.
ArrayLiteral : [ ElementList ]
  1. array를 ! ArrayCreate(0)로 한다.
  2. ArrayAccumulationElementList에 대해 array와 0을 인수로 호출하여 수행한다.
  3. array를 반환한다.
ArrayLiteral : [ ElementList , Elisionopt ]
  1. array를 ! ArrayCreate(0)로 한다.
  2. nextIndex를 ? ArrayAccumulationElementList에 대해 array와 0을 인수로 호출한 결과로 한다.
  3. Elision이 존재하면,
    1. ArrayAccumulationElision에 대해 arraynextIndex를 인수로 호출하여 수행한다.
  4. array를 반환한다.

13.2.5 객체 이니셜라이저

참고 1

객체 이니셜라이저는 객체(Object)의 초기화를 기술하는 표현식으로, 리터럴과 유사한 형태로 작성된다. 중괄호로 감싸진 0개 이상의 프로퍼티 키와 해당 값의 쌍의 리스트이다. 값은 반드시 리터럴일 필요는 없으며, 객체 이니셜라이저가 평가될 때마다 각각 평가된다.

구문

ObjectLiteral[Yield, Await] : { } { PropertyDefinitionList[?Yield, ?Await] } { PropertyDefinitionList[?Yield, ?Await] , } PropertyDefinitionList[Yield, Await] : PropertyDefinition[?Yield, ?Await] PropertyDefinitionList[?Yield, ?Await] , PropertyDefinition[?Yield, ?Await] PropertyDefinition[Yield, Await] : IdentifierReference[?Yield, ?Await] CoverInitializedName[?Yield, ?Await] PropertyName[?Yield, ?Await] : AssignmentExpression[+In, ?Yield, ?Await] MethodDefinition[?Yield, ?Await] ... AssignmentExpression[+In, ?Yield, ?Await] PropertyName[Yield, Await] : LiteralPropertyName ComputedPropertyName[?Yield, ?Await] LiteralPropertyName : IdentifierName StringLiteral NumericLiteral ComputedPropertyName[Yield, Await] : [ AssignmentExpression[+In, ?Yield, ?Await] ] CoverInitializedName[Yield, Await] : IdentifierReference[?Yield, ?Await] Initializer[+In, ?Yield, ?Await] Initializer[In, Yield, Await] : = AssignmentExpression[?In, ?Yield, ?Await] 참고 2

MethodDefinition15.4에서 정의된다.

참고 3

특정 맥락에서는 ObjectLiteral이 더 제한적인 2차 문법을 감싸는 커버 문법으로 사용된다. CoverInitializedName 생성규칙은 이러한 2차 문법을 완전히 커버하기 위해 필요하다. 그러나 이 생성규칙을 사용하는 경우, 실제 ObjectLiteral이 기대되는 일반적인 맥락에서는 초기 구문 에러가 발생한다.

13.2.5.1 정적 의미: 초기 에러

PropertyDefinition : MethodDefinition

실제 객체 이니셜라이저를 설명하는 것 이외에도, ObjectLiteral 생성규칙은 ObjectAssignmentPattern의 커버 문법(cover grammar)으로도 사용될 수 있으며, CoverParenthesizedExpressionAndArrowParameterList의 일부로 인식될 수 있다. ObjectLiteralObjectAssignmentPattern이 요구되는 문맥에 나타나는 경우, 아래 초기 에러 규칙들은 적용되지 않는다. 또한, CoverParenthesizedExpressionAndArrowParameterList 또는 CoverCallExpressionAndAsyncArrowHead을 처음 파싱할 때도 적용되지 않는다.

PropertyDefinition : CoverInitializedName
  • 이 생성규칙에 소스 텍스트가 일치하면 구문 에러이다.
참고 1

이 생성규칙은 ObjectLiteralObjectAssignmentPattern의 커버 문법으로 사용될 수 있도록 존재한다. 실제 객체 이니셜라이저에는 등장할 수 없다.

ObjectLiteral : { PropertyDefinitionList } { PropertyDefinitionList , } 참고 2

PropertyNameList가 반환하는 List에는 ComputedPropertyName을 사용하여 정의된 프로퍼티 이름이 포함되지 않는다.

13.2.5.2 정적 의미: IsComputedPropertyKey

구문-지시 연산 IsComputedPropertyKey는 인수를 받지 않으며 불리언을 반환한다. 다음 생성규칙에 대해 분할적으로 정의된다:

PropertyName : LiteralPropertyName
  1. false를 반환한다.
PropertyName : ComputedPropertyName
  1. true를 반환한다.

13.2.5.3 정적 의미: PropertyNameList

구문-지시 연산 PropertyNameList는 인수를 받지 않으며 문자열의 List를 반환한다. 다음 생성규칙에 대해 분할적으로 정의된다:

PropertyDefinitionList : PropertyDefinition
  1. propNamePropertyDefinitionPropName으로 한다.
  2. propNameempty이면, 새로운 빈 List를 반환한다.
  3. « propName »를 반환한다.
PropertyDefinitionList : PropertyDefinitionList , PropertyDefinition
  1. listPropertyDefinitionListPropertyNameList로 한다.
  2. propNamePropertyDefinitionPropName로 한다.
  3. propNameempty이면, list를 반환한다.
  4. list와 « propName »의 list-concatenation을 반환한다.

13.2.5.4 런타임 의미: 평가

ObjectLiteral : { }
  1. OrdinaryObjectCreate(%Object.prototype%)를 반환한다.
ObjectLiteral : { PropertyDefinitionList } { PropertyDefinitionList , }
  1. objOrdinaryObjectCreate(%Object.prototype%)로 한다.
  2. PropertyDefinitionListPropertyDefinitionEvaluationobj를 인수로 하여 호출한다.
  3. obj를 반환한다.
LiteralPropertyName : IdentifierName
  1. IdentifierNameStringValue를 반환한다.
LiteralPropertyName : StringLiteral
  1. StringLiteralSV를 반환한다.
LiteralPropertyName : NumericLiteral
  1. nbrNumericLiteralNumericValue로 한다.
  2. ToString(nbr)을 반환한다.
ComputedPropertyName : [ AssignmentExpression ]
  1. exprValue를 ? EvaluationAssignmentExpression에 대해 호출한 결과로 한다.
  2. propName을 ? GetValue(exprValue)로 한다.
  3. ToPropertyKey(propName)를 반환한다.

13.2.5.5 런타임 의미: PropertyDefinitionEvaluation

구문-지시 연산 PropertyDefinitionEvaluation은 인수 object(객체)를 받고, 정상 완료(normal completion) unused 또는 비정상 완료(abrupt completion)를 반환한다. 다음 생성규칙에 대해 분할적으로 정의된다:

PropertyDefinitionList : PropertyDefinitionList , PropertyDefinition
  1. PropertyDefinitionEvaluationPropertyDefinitionList에 대해 object를 인수로 호출하여 수행한다.
  2. PropertyDefinitionEvaluationPropertyDefinition에 대해 object를 인수로 호출하여 수행한다.
  3. unused를 반환한다.
PropertyDefinition : ... AssignmentExpression
  1. exprValue를 ? EvaluationAssignmentExpression에 대해 호출한 결과로 한다.
  2. fromValue를 ? GetValue(exprValue)로 한다.
  3. excludedNames를 새로운 빈 List로 한다.
  4. CopyDataProperties(object, fromValue, excludedNames)를 수행한다.
  5. unused를 반환한다.
PropertyDefinition : IdentifierReference
  1. propNameIdentifierReferenceStringValue로 한다.
  2. exprValue를 ? EvaluationIdentifierReference에 대해 호출한 결과로 한다.
  3. propValue를 ? GetValue(exprValue)로 한다.
  4. Assert: object는 일반적이고 확장 가능한 객체이며 비구성 가능(non-configurable) 속성이 없어야 한다.
  5. CreateDataPropertyOrThrow(object, propName, propValue)를 수행한다.
  6. unused를 반환한다.
PropertyDefinition : PropertyName : AssignmentExpression
  1. propKey를 ? EvaluationPropertyName에 대해 호출한 결과로 한다.
  2. PropertyDefinitionParseJSON을 위해 평가 중인 Script 내에 포함되어 있다면,
    1. isProtoSetterfalse로 한다.
  3. 그렇지 않고, propKey"__proto__"이고 PropertyNameIsComputedPropertyKeyfalse라면,
    1. isProtoSettertrue로 한다.
  4. 그 외의 경우,
    1. isProtoSetterfalse로 한다.
  5. IsAnonymousFunctionDefinition(AssignmentExpression)이 true이고, isProtoSetterfalse라면,
    1. propValue를 ? NamedEvaluationAssignmentExpressionpropKey를 인수로 호출한 결과로 한다.
  6. 그 외의 경우,
    1. exprValueRef를 ? EvaluationAssignmentExpression에 대해 호출한 결과로 한다.
    2. propValue를 ? GetValue(exprValueRef)로 한다.
  7. isProtoSettertrue라면,
    1. propValue객체이거나 propValuenull이라면,
      1. object.[[SetPrototypeOf]](propValue)를 수행한다.
    2. unused를 반환한다.
  8. Assert: object는 일반적이고 확장 가능한 객체이며 비구성 가능(non-configurable) 속성이 없어야 한다.
  9. CreateDataPropertyOrThrow(object, propKey, propValue)를 수행한다.
  10. unused를 반환한다.
PropertyDefinition : MethodDefinition
  1. MethodDefinitionEvaluationMethodDefinition에 대해 objecttrue를 인수로 호출하여 수행한다.
  2. unused를 반환한다.

13.2.6 함수 정의 표현식

15.2에서 PrimaryExpression : FunctionExpression 를 참조하라.

15.5에서 PrimaryExpression : GeneratorExpression 를 참조하라.

15.7에서 PrimaryExpression : ClassExpression 를 참조하라.

15.8에서 PrimaryExpression : AsyncFunctionExpression 를 참조하라.

15.6에서 PrimaryExpression : AsyncGeneratorExpression 를 참조하라.

13.2.7 정규 표현식 리터럴

구문

12.9.5를 참조하라.

13.2.7.1 정적 의미: 초기 에러

PrimaryExpression : RegularExpressionLiteral

13.2.7.2 정적 의미: IsValidRegularExpressionLiteral ( literal )

추상 연산 IsValidRegularExpressionLiteral은 인수 literal(RegularExpressionLiteral 파스 노드)를 받고 불리언을 반환한다. 이 연산은 인수가 유효한 정규 표현식 리터럴인지 판단한다. 호출 시 다음 단계를 수행한다:

  1. flagsliteralFlagText로 한다.
  2. flagsd, g, i, m, s, u, v, y 이외의 코드 포인트가 포함되어 있거나, flags에 동일한 코드 포인트가 두 번 이상 포함되어 있으면 false를 반환한다.
  3. flagsu가 포함되어 있으면 utrue로, 아니면 false로 한다.
  4. flagsv가 포함되어 있으면 vtrue로, 아니면 false로 한다.
  5. patternTextliteralBodyText로 한다.
  6. ufalse이고 vfalse이면,
    1. stringValueCodePointsToString(patternText)로 한다.
    2. patternTextstringValue의 각 16비트 요소를 유니코드 BMP 코드 포인트로 해석하여 얻은 코드 포인트 시퀀스로 설정한다. UTF-16 디코딩은 적용하지 않는다.
  7. parseResultParsePattern(patternText, u, v)로 한다.
  8. parseResult파스 노드라면 true를, 그렇지 않으면 false를 반환한다.

13.2.7.3 런타임 의미: 평가

PrimaryExpression : RegularExpressionLiteral
  1. patternCodePointsToString(BodyText of RegularExpressionLiteral)로 한다.
  2. flagsCodePointsToString(FlagText of RegularExpressionLiteral)로 한다.
  3. RegExpCreate(pattern, flags)를 반환한다.

13.2.8 템플릿 리터럴

구문

TemplateLiteral[Yield, Await, Tagged] : NoSubstitutionTemplate SubstitutionTemplate[?Yield, ?Await, ?Tagged] SubstitutionTemplate[Yield, Await, Tagged] : TemplateHead Expression[+In, ?Yield, ?Await] TemplateSpans[?Yield, ?Await, ?Tagged] TemplateSpans[Yield, Await, Tagged] : TemplateTail TemplateMiddleList[?Yield, ?Await, ?Tagged] TemplateTail TemplateMiddleList[Yield, Await, Tagged] : TemplateMiddle Expression[+In, ?Yield, ?Await] TemplateMiddleList[?Yield, ?Await, ?Tagged] TemplateMiddle Expression[+In, ?Yield, ?Await]

13.2.8.1 정적 의미론: 초기 에러

TemplateLiteral[Yield, Await, Tagged] : NoSubstitutionTemplate TemplateLiteral[Yield, Await, Tagged] : SubstitutionTemplate[?Yield, ?Await, ?Tagged] SubstitutionTemplate[Yield, Await, Tagged] : TemplateHead Expression[+In, ?Yield, ?Await] TemplateSpans[?Yield, ?Await, ?Tagged] TemplateSpans[Yield, Await, Tagged] : TemplateTail TemplateMiddleList[Yield, Await, Tagged] : TemplateMiddle Expression[+In, ?Yield, ?Await] TemplateMiddleList[?Yield, ?Await, ?Tagged] TemplateMiddle Expression[+In, ?Yield, ?Await]

13.2.8.2 정적 의미론: TemplateStrings

구문 지향 연산 TemplateStrings는 raw (불리언)를 인수로 받고, 문자열 또는 undefined리스트를 반환한다. 이는 다음 생산식들에 대해 부분적으로 정의된다:

TemplateLiteral : NoSubstitutionTemplate
  1. « TemplateString(NoSubstitutionTemplate, raw) »를 반환한다.
SubstitutionTemplate : TemplateHead Expression TemplateSpans
  1. head를 « TemplateString(TemplateHead, raw) »로 한다.
  2. tailTemplateStrings of TemplateSpans with argument raw로 한다.
  3. headtail리스트 결합을 반환한다.
TemplateSpans : TemplateTail
  1. « TemplateString(TemplateTail, raw) »를 반환한다.
TemplateSpans : TemplateMiddleList TemplateTail
  1. middleTemplateStrings of TemplateMiddleList with argument raw로 한다.
  2. tail을 « TemplateString(TemplateTail, raw) »로 한다.
  3. middletail리스트 결합을 반환한다.
TemplateMiddleList : TemplateMiddle Expression
  1. « TemplateString(TemplateMiddle, raw) »를 반환한다.
TemplateMiddleList : TemplateMiddleList TemplateMiddle Expression
  1. frontTemplateStrings of TemplateMiddleList with argument raw로 한다.
  2. last를 « TemplateString(TemplateMiddle, raw) »로 한다.
  3. frontlast리스트 결합을 반환한다.

13.2.8.3 정적 의미론: TemplateString ( templateToken, raw )

추상 연산 TemplateString은 templateToken (NoSubstitutionTemplate 파스 노드, TemplateHead 파스 노드, TemplateMiddle 파스 노드, 또는 TemplateTail 파스 노드)와 raw (불리언)를 인수로 받고, 문자열 또는 undefined를 반환한다. 호출 시 다음 단계를 수행한다:

  1. 만약 rawtrue이면,
    1. stringTRV of templateToken으로 한다.
  2. 그 외에는,
    1. stringTV of templateToken으로 한다.
  3. string을 반환한다.
참고

이 연산은 rawfalse이고 templateTokenNotEscapeSequence가 포함된 경우 undefined를 반환한다. 그 외의 경우에는 문자열을 반환한다.

13.2.8.4 GetTemplateObject ( templateLiteral )

추상 연산 GetTemplateObject는 templateLiteral (파스 노드)를 인수로 받고, 배열을 반환한다. 호출 시 다음 단계를 수행한다:

  1. realm현재 Realm Record로 한다.
  2. templateRegistryrealm.[[TemplateMap]]으로 한다.
  3. templateRegistry의 각 요소 e에 대해,
    1. 만약 e.[[Site]]동일한 파스 노드templateLiteral과 같다면,
      1. e.[[Array]]를 반환한다.
  4. rawStringsTemplateStrings of templateLiteral with argument true로 한다.
  5. Assert: rawStrings문자열 리스트이다.
  6. cookedStringsTemplateStrings of templateLiteral with argument false로 한다.
  7. count리스트 cookedStrings의 요소 개수로 한다.
  8. Assert: count ≤ 232 - 1.
  9. template을 ! ArrayCreate(count)로 한다.
  10. rawObj를 ! ArrayCreate(count)로 한다.
  11. index를 0으로 한다.
  12. index < count 동안 반복,
    1. prop을 ! ToString(𝔽(index))로 한다.
    2. cookedValuecookedStrings[index]로 한다.
    3. DefinePropertyOrThrow(template, prop, PropertyDescriptor { [[Value]]: cookedValue, [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: false })를 수행한다.
    4. rawValuerawStrings[index]로 한다.
    5. DefinePropertyOrThrow(rawObj, prop, PropertyDescriptor { [[Value]]: rawValue, [[Writable]]: false, [[Enumerable]]: true, [[Configurable]]: false })를 수행한다.
    6. indexindex + 1로 한다.
  13. SetIntegrityLevel(rawObj, frozen)을 수행한다.
  14. DefinePropertyOrThrow(template, "raw", PropertyDescriptor { [[Value]]: rawObj, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false })를 수행한다.
  15. SetIntegrityLevel(template, frozen)을 수행한다.
  16. Record { [[Site]]: templateLiteral, [[Array]]: template }를 realm.[[TemplateMap]]에 추가한다.
  17. template을 반환한다.
참고 1

템플릿 객체의 생성은 비정상 완료를 일으킬 수 없다.

참고 2

realm의 프로그램 코드에 있는 각 TemplateLiteral는 태그드 템플릿 평가에 사용되는 고유한 템플릿 객체와 연결되어 있다 (13.2.8.6). 템플릿 객체는 frozen 상태이며, 특정 태그드 템플릿이 평가될 때마다 동일한 템플릿 객체가 사용된다. 템플릿 객체가 TemplateLiteral의 첫 평가 시점에 지연 생성(lazy)되는지 혹은 사전에 미리 생성되는지는 구현 선택 사항이며, ECMAScript 코드에서는 관찰할 수 없다.

참고 3

이 명세의 미래 버전에서는 템플릿 객체의 추가적인 non-enumerable 프로퍼티가 정의될 수 있다.

13.2.8.5 런타임 의미론: SubstitutionEvaluation

구문 지향 연산 SubstitutionEvaluation은 인수를 받지 않으며, 리스트비정상 완료를 반환한다. 다음 생산식들에 대해 정의된다:

TemplateSpans : TemplateTail
  1. 새로운 빈 리스트를 반환한다.
TemplateSpans : TemplateMiddleList TemplateTail
  1. SubstitutionEvaluation of TemplateMiddleList의 결과를 반환한다.
TemplateMiddleList : TemplateMiddle Expression
  1. subRef를 ? Evaluation of Expression의 결과로 한다.
  2. sub를 ? GetValue(subRef)로 한다.
  3. « sub »를 반환한다.
TemplateMiddleList : TemplateMiddleList TemplateMiddle Expression
  1. preceding을 ? SubstitutionEvaluation of TemplateMiddleList의 결과로 한다.
  2. nextRef를 ? Evaluation of Expression의 결과로 한다.
  3. next를 ? GetValue(nextRef)로 한다.
  4. preceding과 « next »의 리스트 결합을 반환한다.

13.2.8.6 런타임 의미론: 평가

TemplateLiteral : NoSubstitutionTemplate
  1. TV of NoSubstitutionTemplate12.9.6에 정의된 대로 반환한다.
SubstitutionTemplate : TemplateHead Expression TemplateSpans
  1. headTV of TemplateHead로 하고, 12.9.6에 정의된 대로 한다.
  2. subRef를 ? Evaluation of Expression의 결과로 한다.
  3. sub를 ? GetValue(subRef)로 한다.
  4. middle을 ? ToString(sub)로 한다.
  5. tail을 ? Evaluation of TemplateSpans의 결과로 한다.
  6. head, middle, tail문자열 결합을 반환한다.
참고 1

Expression 값에 적용되는 문자열 변환 의미는 String.prototype.concat과 같으며 + 연산자와는 다르다.

TemplateSpans : TemplateTail
  1. TV of TemplateTail12.9.6에 정의된 대로 반환한다.
TemplateSpans : TemplateMiddleList TemplateTail
  1. head를 ? Evaluation of TemplateMiddleList의 결과로 한다.
  2. tailTV of TemplateTail12.9.6에 정의된 대로 한다.
  3. headtail문자열 결합을 반환한다.
TemplateMiddleList : TemplateMiddle Expression
  1. headTV of TemplateMiddle12.9.6에 정의된 대로 한다.
  2. subRef를 ? Evaluation of Expression의 결과로 한다.
  3. sub를 ? GetValue(subRef)로 한다.
  4. middle을 ? ToString(sub)로 한다.
  5. headmiddle문자열 결합을 반환한다.
참고 2

Expression 값에 적용되는 문자열 변환 의미는 String.prototype.concat과 같으며 + 연산자와는 다르다.

TemplateMiddleList : TemplateMiddleList TemplateMiddle Expression
  1. rest를 ? Evaluation of TemplateMiddleList의 결과로 한다.
  2. middleTV of TemplateMiddle12.9.6에 정의된 대로 한다.
  3. subRef를 ? Evaluation of Expression의 결과로 한다.
  4. sub를 ? GetValue(subRef)로 한다.
  5. last를 ? ToString(sub)로 한다.
  6. rest, middle, last문자열 결합을 반환한다.
참고 3

Expression 값에 적용되는 문자열 변환 의미는 String.prototype.concat과 같으며 + 연산자와는 다르다.

13.2.9 그룹화 연산자

13.2.9.1 정적 의미론: 초기 에러

PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList

13.2.9.2 런타임 의미론: 평가

PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList
  1. exprParenthesizedExpression로 한다. 이는 포함된 CoverParenthesizedExpressionAndArrowParameterList이다.
  2. Evaluation of expr를 반환한다.
ParenthesizedExpression : ( Expression )
  1. Evaluation of Expression을 반환한다. 이 값은 Reference 타입일 수 있다.
참고

이 알고리즘은 Evaluation of Expression의 결과에 GetValue를 적용하지 않는다. 그 주요 동기는 deletetypeof와 같은 연산자가 괄호로 묶인 표현식에 적용될 수 있도록 하기 위함이다.

13.3 좌변식(Left-Hand-Side Expressions)

구문

MemberExpression[Yield, Await] : PrimaryExpression[?Yield, ?Await] MemberExpression[?Yield, ?Await] [ Expression[+In, ?Yield, ?Await] ] MemberExpression[?Yield, ?Await] . IdentifierName MemberExpression[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged] SuperProperty[?Yield, ?Await] MetaProperty new MemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await] MemberExpression[?Yield, ?Await] . PrivateIdentifier SuperProperty[Yield, Await] : super [ Expression[+In, ?Yield, ?Await] ] super . IdentifierName MetaProperty : NewTarget ImportMeta NewTarget : new . target ImportMeta : import . meta NewExpression[Yield, Await] : MemberExpression[?Yield, ?Await] new NewExpression[?Yield, ?Await] CallExpression[Yield, Await] : CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await] SuperCall[?Yield, ?Await] ImportCall[?Yield, ?Await] CallExpression[?Yield, ?Await] Arguments[?Yield, ?Await] CallExpression[?Yield, ?Await] [ Expression[+In, ?Yield, ?Await] ] CallExpression[?Yield, ?Await] . IdentifierName CallExpression[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged] CallExpression[?Yield, ?Await] . PrivateIdentifier SuperCall[Yield, Await] : super Arguments[?Yield, ?Await] ImportCall[Yield, Await] : import ( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) import ( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) Arguments[Yield, Await] : ( ) ( ArgumentList[?Yield, ?Await] ) ( ArgumentList[?Yield, ?Await] , ) ArgumentList[Yield, Await] : AssignmentExpression[+In, ?Yield, ?Await] ... AssignmentExpression[+In, ?Yield, ?Await] ArgumentList[?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ArgumentList[?Yield, ?Await] , ... AssignmentExpression[+In, ?Yield, ?Await] OptionalExpression[Yield, Await] : MemberExpression[?Yield, ?Await] OptionalChain[?Yield, ?Await] CallExpression[?Yield, ?Await] OptionalChain[?Yield, ?Await] OptionalExpression[?Yield, ?Await] OptionalChain[?Yield, ?Await] OptionalChain[Yield, Await] : ?. Arguments[?Yield, ?Await] ?. [ Expression[+In, ?Yield, ?Await] ] ?. IdentifierName ?. TemplateLiteral[?Yield, ?Await, +Tagged] ?. PrivateIdentifier OptionalChain[?Yield, ?Await] Arguments[?Yield, ?Await] OptionalChain[?Yield, ?Await] [ Expression[+In, ?Yield, ?Await] ] OptionalChain[?Yield, ?Await] . IdentifierName OptionalChain[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged] OptionalChain[?Yield, ?Await] . PrivateIdentifier LeftHandSideExpression[Yield, Await] : NewExpression[?Yield, ?Await] CallExpression[?Yield, ?Await] OptionalExpression[?Yield, ?Await]

보충 구문

다음 생성식을 처리할 때
CallExpression : CoverCallExpressionAndAsyncArrowHead
CoverCallExpressionAndAsyncArrowHead의 해석은 다음 문법을 사용하여 보완된다:

CallMemberExpression[Yield, Await] : MemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await]

13.3.1 정적 의미론

13.3.1.1 정적 의미론: 초기 에러

OptionalChain : ?. TemplateLiteral OptionalChain TemplateLiteral
  • 이 생성식에 의해 소스 텍스트가 일치하는 경우 구문 오류이다.
참고

이 생성식은 다음 코드에 자동 세미콜론 삽입 규칙(12.10)이 적용되는 것을 방지하기 위해 존재한다:

a?.b
`c`

이 코드는 두 개의 유효한 문장으로 해석되어야 한다. 목적은 선택적 체이닝 없이 유사한 코드와 일관성을 유지하는 것이다:

a.b
`c`

이 코드는 유효한 문장이며, 자동 세미콜론 삽입이 적용되지 않는다.

ImportMeta : import . meta

13.3.2 프로퍼티 접근자

참고

프로퍼티는 점 표기법(dot notation)을 사용하여 이름으로 접근할 수 있다:

또는 대괄호 표기법(bracket notation)을 사용할 수 있다:

점 표기법은 다음 구문 변환에 의해 설명된다:

이는 동작상 다음과 동일하다:

MemberExpression [ <identifier-name-string> ]

그리고 마찬가지로

이는 동작상 다음과 동일하다:

CallExpression [ <identifier-name-string> ]

여기서 <identifier-name-string>은 IdentifierNameStringValue이다.

13.3.2.1 런타임 의미론: 평가

MemberExpression : MemberExpression [ Expression ]
  1. baseReference를 ? Evaluation of MemberExpression의 결과로 한다.
  2. baseValue를 ? GetValue(baseReference)로 한다.
  3. strictIsStrict(this MemberExpression)로 한다.
  4. EvaluatePropertyAccessWithExpressionKey(baseValue, Expression, strict)를 반환한다.
MemberExpression : MemberExpression . IdentifierName
  1. baseReference를 ? Evaluation of MemberExpression의 결과로 한다.
  2. baseValue를 ? GetValue(baseReference)로 한다.
  3. strictIsStrict(this MemberExpression)로 한다.
  4. EvaluatePropertyAccessWithIdentifierKey(baseValue, IdentifierName, strict)를 반환한다.
MemberExpression : MemberExpression . PrivateIdentifier
  1. baseReference를 ? Evaluation of MemberExpression의 결과로 한다.
  2. baseValue를 ? GetValue(baseReference)로 한다.
  3. fieldNameStringStringValue of PrivateIdentifier로 한다.
  4. MakePrivateReference(baseValue, fieldNameString)를 반환한다.
CallExpression : CallExpression [ Expression ]
  1. baseReference를 ? Evaluation of CallExpression의 결과로 한다.
  2. baseValue를 ? GetValue(baseReference)로 한다.
  3. strictIsStrict(this CallExpression)로 한다.
  4. EvaluatePropertyAccessWithExpressionKey(baseValue, Expression, strict)를 반환한다.
CallExpression : CallExpression . IdentifierName
  1. baseReference를 ? Evaluation of CallExpression의 결과로 한다.
  2. baseValue를 ? GetValue(baseReference)로 한다.
  3. strictIsStrict(this CallExpression)로 한다.
  4. EvaluatePropertyAccessWithIdentifierKey(baseValue, IdentifierName, strict)를 반환한다.
CallExpression : CallExpression . PrivateIdentifier
  1. baseReference를 ? Evaluation of CallExpression의 결과로 한다.
  2. baseValue를 ? GetValue(baseReference)로 한다.
  3. fieldNameStringStringValue of PrivateIdentifier로 한다.
  4. MakePrivateReference(baseValue, fieldNameString)를 반환한다.

13.3.3 EvaluatePropertyAccessWithExpressionKey ( baseValue, expression, strict )

추상 연산 EvaluatePropertyAccessWithExpressionKey는 baseValue (ECMAScript 언어 값), expression (Expression 파스 노드), strict (불리언)를 인수로 받고, 정상 완료(normal completion)가 담긴 Reference Record 또는 비정상 완료(abrupt completion)를 반환한다. 실행 시 다음 단계를 수행한다:

  1. propertyNameReference를 ? Evaluation of expression의 결과로 한다.
  2. propertyNameValue를 ? GetValue(propertyNameReference)로 한다.
  3. 참고: 대부분의 경우 ToPropertyKey가 이 단계 바로 뒤에 propertyNameValue에 적용된다. 하지만 a[b] = c의 경우 c의 평가가 끝난 뒤에 적용된다.
  4. Reference Record { [[Base]]: baseValue, [[ReferencedName]]: propertyNameValue, [[Strict]]: strict, [[ThisValue]]: empty }를 반환한다.

13.3.4 EvaluatePropertyAccessWithIdentifierKey ( baseValue, identifierName, strict )

추상 연산 EvaluatePropertyAccessWithIdentifierKey는 baseValue (ECMAScript 언어 값), identifierName (IdentifierName 파스 노드), strict (불리언)를 인수로 받고, Reference Record를 반환한다. 실행 시 다음 단계를 수행한다:

  1. propertyNameStringStringValue of identifierName로 한다.
  2. Reference Record { [[Base]]: baseValue, [[ReferencedName]]: propertyNameString, [[Strict]]: strict, [[ThisValue]]: empty }를 반환한다.

13.3.5 new 연산자

13.3.5.1 런타임 의미론: 평가

NewExpression : new NewExpression
  1. EvaluateNew(NewExpression, empty)를 반환한다.
MemberExpression : new MemberExpression Arguments
  1. EvaluateNew(MemberExpression, Arguments)를 반환한다.

13.3.5.1.1 EvaluateNew ( constructExpr, arguments )

추상 연산 EvaluateNew는 constructExpr (NewExpression 파스 노드 또는 MemberExpression 파스 노드)와 arguments (empty 또는 Arguments 파스 노드)를 인수로 받고, 정상 완료(normal completion)가 담긴 ECMAScript 언어 값 또는 비정상 완료(abrupt completion)를 반환한다. 실행 시 다음 단계를 수행한다:

  1. ref를 ? Evaluation of constructExpr의 결과로 한다.
  2. constructor를 ? GetValue(ref)로 한다.
  3. 만약 argumentsempty이면,
    1. argList를 새로운 빈 리스트로 한다.
  4. 그 외에는,
    1. argList를 ? ArgumentListEvaluation of arguments의 결과로 한다.
  5. IsConstructor(constructor) 가 false이면 TypeError 예외를 throw한다.
  6. Construct(constructor, argList)를 반환한다.

13.3.6 함수 호출

13.3.6.1 런타임 의미론: 평가

CallExpression : CoverCallExpressionAndAsyncArrowHead
  1. exprCallMemberExpression로 한다. 이는 포함된 CoverCallExpressionAndAsyncArrowHead이다.
  2. memberExprexprMemberExpression로 한다.
  3. argumentsexprArguments로 한다.
  4. ref를 ? Evaluation of memberExpr의 결과로 한다.
  5. func를 ? GetValue(ref)로 한다.
  6. 만약 refReference Record이고, IsPropertyReference(ref) 가 false이며, ref.[[ReferencedName]]"eval"이면,
    1. SameValue(func, %eval%)가 true이면,
      1. argList를 ? ArgumentListEvaluation of arguments의 결과로 한다.
      2. argList에 요소가 없다면 undefined를 반환한다.
      3. evalArgargList의 첫 번째 요소로 한다.
      4. IsStrict(this CallExpression)가 true이면 strictCallertrue로, 그렇지 않으면 strictCallerfalse로 한다.
      5. PerformEval(evalArg, strictCaller, true)의 결과를 반환한다.
  7. thisCall을 this CallExpression로 한다.
  8. tailCallIsInTailPosition(thisCall)로 한다.
  9. EvaluateCall(func, ref, arguments, tailCall)의 결과를 반환한다.

CallExpression의 평가가 6.a.v 단계를 실행하면, 이는 직접 eval(direct eval)이다.

CallExpression : CallExpression Arguments
  1. ref를 ? Evaluation of CallExpression의 결과로 한다.
  2. func를 ? GetValue(ref)로 한다.
  3. thisCall을 this CallExpression로 한다.
  4. tailCallIsInTailPosition(thisCall)로 한다.
  5. EvaluateCall(func, ref, Arguments, tailCall)의 결과를 반환한다.

13.3.6.2 EvaluateCall ( func, ref, arguments, tailPosition )

추상 연산 EvaluateCall은 func (ECMAScript 언어 값), ref (ECMAScript 언어 값 또는 Reference Record), arguments (파스 노드), tailPosition (불리언)를 인수로 받고, 정상 완료가 담긴 ECMAScript 언어 값 또는 비정상 완료를 반환한다. 호출 시 다음 단계를 수행한다:

  1. refReference Record라면,
    1. IsPropertyReference(ref) 가 true라면,
      1. thisValueGetThisValue(ref)로 한다.
    2. 그 외에는,
      1. refEnvref.[[Base]]로 한다.
      2. Assert: refEnvEnvironment Record이다.
      3. thisValuerefEnv.WithBaseObject()로 한다.
  2. 그 외에는,
    1. thisValueundefined로 한다.
  3. argList를 ? ArgumentListEvaluation of arguments의 결과로 한다.
  4. func객체가 아니면 TypeError 예외를 throw한다.
  5. IsCallable(func)가 false이면 TypeError 예외를 throw한다.
  6. tailPositiontrue이면, PrepareForTailCall()를 수행한다.
  7. Call(func, thisValue, argList)의 결과를 반환한다.

13.3.7 super 키워드

13.3.7.1 런타임 의미론: 평가

SuperProperty : super [ Expression ]
  1. envGetThisEnvironment()로 한다.
  2. actualThis를 ? env.GetThisBinding()으로 한다.
  3. propertyNameReference를 ? Evaluation of Expression의 결과로 한다.
  4. propertyNameValue를 ? GetValue(propertyNameReference)로 한다.
  5. strictIsStrict(this SuperProperty)로 한다.
  6. 참고: 대부분의 경우, ToPropertyKey가 이 단계 직후 propertyNameValue에 대해 수행된다. 그러나 super[b] = c의 경우 c의 평가가 끝난 뒤에 수행된다.
  7. MakeSuperPropertyReference(actualThis, propertyNameValue, strict)를 반환한다.
SuperProperty : super . IdentifierName
  1. envGetThisEnvironment()로 한다.
  2. actualThis를 ? env.GetThisBinding()으로 한다.
  3. propertyKeyStringValue of IdentifierName로 한다.
  4. strictIsStrict(this SuperProperty)로 한다.
  5. MakeSuperPropertyReference(actualThis, propertyKey, strict)를 반환한다.
SuperCall : super Arguments
  1. newTargetGetNewTarget()로 한다.
  2. Assert: newTarget생성자이다.
  3. funcGetSuperConstructor()로 한다.
  4. argList를 ? ArgumentListEvaluation of Arguments의 결과로 한다.
  5. IsConstructor(func)가 false이면 TypeError 예외를 throw한다.
  6. result를 ? Construct(func, argList, newTarget)의 결과로 한다.
  7. thisERGetThisEnvironment()로 한다.
  8. Assert: thisER함수 환경 레코드(Function Environment Record)이다.
  9. BindThisValue(thisER, result)를 수행한다.
  10. FthisER.[[FunctionObject]]로 한다.
  11. Assert: F는 ECMAScript 함수 객체(function object)이다.
  12. InitializeInstanceElements(result, F)를 수행한다.
  13. result를 반환한다.

13.3.7.2 GetSuperConstructor ( )

추상 연산 GetSuperConstructor는 인수를 받지 않으며 ECMAScript 언어 값을 반환한다. 호출 시 다음 단계를 수행한다:

  1. envRecGetThisEnvironment()로 한다.
  2. Assert: envRec함수 환경 레코드(Function Environment Record)이다.
  3. activeFunctionenvRec.[[FunctionObject]]로 한다.
  4. Assert: activeFunction은 ECMAScript 함수 객체(function object)이다.
  5. superConstructor를 ! activeFunction.[[GetPrototypeOf]]()의 결과로 한다.
  6. superConstructor를 반환한다.

13.3.7.3 MakeSuperPropertyReference ( actualThis, propertyKey, strict )

추상 연산 MakeSuperPropertyReference는 actualThis (ECMAScript 언어 값), propertyKey (ECMAScript 언어 값), strict (불리언)를 인수로 받고, Super Reference Record를 반환한다. 호출 시 다음 단계를 수행한다:

  1. envGetThisEnvironment()로 한다.
  2. Assert: env.HasSuperBinding()이 true이다.
  3. Assert: env함수 환경 레코드(Function Environment Record)이다.
  4. baseValueGetSuperBase(env)로 한다.
  5. Reference Record { [[Base]]: baseValue, [[ReferencedName]]: propertyKey, [[Strict]]: strict, [[ThisValue]]: actualThis }를 반환한다.

13.3.8 인수 목록

참고

인수 목록의 평가는 값들의 리스트를 생성한다.

13.3.8.1 런타임 의미론: ArgumentListEvaluation

구문 지향 연산 ArgumentListEvaluation은 인수를 받지 않으며, 리스트에 담긴 ECMAScript 언어 값들의 정상 완료(normal completion) 또는 비정상 완료(abrupt completion)를 반환한다. 다음 생산식에 대해 부분적으로 정의된다:

Arguments : ( )
  1. 새로운 빈 리스트를 반환한다.
ArgumentList : AssignmentExpression
  1. ref를 ? Evaluation of AssignmentExpression의 결과로 한다.
  2. arg를 ? GetValue(ref)로 한다.
  3. « arg »를 반환한다.
ArgumentList : ... AssignmentExpression
  1. list를 새로운 빈 리스트로 한다.
  2. spreadRef를 ? Evaluation of AssignmentExpression의 결과로 한다.
  3. spreadObj를 ? GetValue(spreadRef)로 한다.
  4. iteratorRecord를 ? GetIterator(spreadObj, sync)로 한다.
  5. 반복,
    1. next를 ? IteratorStepValue(iteratorRecord)로 한다.
    2. nextdone이면 list를 반환한다.
    3. nextlist에 추가한다.
ArgumentList : ArgumentList , AssignmentExpression
  1. precedingArgs를 ? ArgumentListEvaluation of ArgumentList의 결과로 한다.
  2. ref를 ? Evaluation of AssignmentExpression의 결과로 한다.
  3. arg를 ? GetValue(ref)로 한다.
  4. precedingArgs와 « arg »의 리스트 결합을 반환한다.
ArgumentList : ArgumentList , ... AssignmentExpression
  1. precedingArgs를 ? ArgumentListEvaluation of ArgumentList의 결과로 한다.
  2. spreadRef를 ? Evaluation of AssignmentExpression의 결과로 한다.
  3. iteratorRecord를 ? GetIterator(? GetValue(spreadRef), sync)로 한다.
  4. 반복,
    1. next를 ? IteratorStepValue(iteratorRecord)로 한다.
    2. nextdone이면 precedingArgs를 반환한다.
    3. nextprecedingArgs에 추가한다.
TemplateLiteral : NoSubstitutionTemplate
  1. templateLiteral을 this TemplateLiteral로 한다.
  2. siteObjGetTemplateObject(templateLiteral)로 한다.
  3. « siteObj »를 반환한다.
TemplateLiteral : SubstitutionTemplate
  1. templateLiteral을 this TemplateLiteral로 한다.
  2. siteObjGetTemplateObject(templateLiteral)로 한다.
  3. remaining을 ? ArgumentListEvaluation of SubstitutionTemplate의 결과로 한다.
  4. « siteObj »와 remaining리스트 결합을 반환한다.
SubstitutionTemplate : TemplateHead Expression TemplateSpans
  1. firstSubRef를 ? Evaluation of Expression의 결과로 한다.
  2. firstSub를 ? GetValue(firstSubRef)로 한다.
  3. restSub를 ? SubstitutionEvaluation of TemplateSpans의 결과로 한다.
  4. Assert: restSub는 비어 있을 수도 있는 리스트이다.
  5. « firstSub »와 restSub리스트 결합을 반환한다.

13.3.9 옵셔널 체이닝

참고
옵셔널 체이닝은 하나 이상의 프로퍼티 접근 또는 함수 호출로 이루어진 체인으로, 그 첫 번째가 ?. 토큰으로 시작한다.

13.3.9.1 런타임 의미론: 평가

OptionalExpression : MemberExpression OptionalChain
  1. baseReference를 ? Evaluation of MemberExpression의 결과로 한다.
  2. baseValue를 ? GetValue(baseReference)로 한다.
  3. 만약 baseValueundefined 또는 null이면,
    1. undefined를 반환한다.
  4. ChainEvaluation of OptionalChainbaseValuebaseReference를 인수로 하여 호출한 결과를 반환한다.
OptionalExpression : CallExpression OptionalChain
  1. baseReference를 ? Evaluation of CallExpression의 결과로 한다.
  2. baseValue를 ? GetValue(baseReference)로 한다.
  3. 만약 baseValueundefined 또는 null이면,
    1. undefined를 반환한다.
  4. ChainEvaluation of OptionalChainbaseValuebaseReference를 인수로 하여 호출한 결과를 반환한다.
OptionalExpression : OptionalExpression OptionalChain
  1. baseReference를 ? Evaluation of OptionalExpression의 결과로 한다.
  2. baseValue를 ? GetValue(baseReference)로 한다.
  3. 만약 baseValueundefined 또는 null이면,
    1. undefined를 반환한다.
  4. ChainEvaluation of OptionalChainbaseValuebaseReference를 인수로 하여 호출한 결과를 반환한다.

13.3.9.2 런타임 의미론: ChainEvaluation

구문 지향 연산 ChainEvaluation은 baseValue (ECMAScript 언어 값), baseReference (ECMAScript 언어 값 또는 Reference Record)를 인수로 받고, 정상 완료(normal completion)가 담긴 ECMAScript 언어 값 또는 Reference Record 또는 비정상 완료(abrupt completion)를 반환한다. 다음 생산식에 대해 부분적으로 정의된다:

OptionalChain : ?. Arguments
  1. thisChain을 this OptionalChain로 한다.
  2. tailCallIsInTailPosition(thisChain)로 한다.
  3. EvaluateCall(baseValue, baseReference, Arguments, tailCall)의 결과를 반환한다.
OptionalChain : ?. [ Expression ]
  1. strictIsStrict(this OptionalChain)로 한다.
  2. EvaluatePropertyAccessWithExpressionKey(baseValue, Expression, strict)의 결과를 반환한다.
OptionalChain : ?. IdentifierName
  1. strictIsStrict(this OptionalChain)로 한다.
  2. EvaluatePropertyAccessWithIdentifierKey(baseValue, IdentifierName, strict)의 결과를 반환한다.
OptionalChain : ?. PrivateIdentifier
  1. fieldNameStringStringValue of PrivateIdentifier로 한다.
  2. MakePrivateReference(baseValue, fieldNameString)의 결과를 반환한다.
OptionalChain : OptionalChain Arguments
  1. optionalChainOptionalChain로 한다.
  2. newReference를 ? ChainEvaluation of optionalChainbaseValuebaseReference를 인수로 하여 호출한 결과로 한다.
  3. newValue를 ? GetValue(newReference)로 한다.
  4. thisChain을 this OptionalChain로 한다.
  5. tailCallIsInTailPosition(thisChain)로 한다.
  6. EvaluateCall(newValue, newReference, Arguments, tailCall)의 결과를 반환한다.
OptionalChain : OptionalChain [ Expression ]
  1. optionalChainOptionalChain로 한다.
  2. newReference를 ? ChainEvaluation of optionalChainbaseValuebaseReference를 인수로 하여 호출한 결과로 한다.
  3. newValue를 ? GetValue(newReference)로 한다.
  4. strictIsStrict(this OptionalChain)로 한다.
  5. EvaluatePropertyAccessWithExpressionKey(newValue, Expression, strict)의 결과를 반환한다.
OptionalChain : OptionalChain . IdentifierName
  1. optionalChainOptionalChain로 한다.
  2. newReference를 ? ChainEvaluation of optionalChainbaseValuebaseReference를 인수로 하여 호출한 결과로 한다.
  3. newValue를 ? GetValue(newReference)로 한다.
  4. strictIsStrict(this OptionalChain)로 한다.
  5. EvaluatePropertyAccessWithIdentifierKey(newValue, IdentifierName, strict)의 결과를 반환한다.
OptionalChain : OptionalChain . PrivateIdentifier
  1. optionalChainOptionalChain로 한다.
  2. newReference를 ? ChainEvaluation of optionalChainbaseValuebaseReference를 인수로 하여 호출한 결과로 한다.
  3. newValue를 ? GetValue(newReference)로 한다.
  4. fieldNameStringStringValue of PrivateIdentifier로 한다.
  5. MakePrivateReference(newValue, fieldNameString)의 결과를 반환한다.

13.3.10 import 호출

13.3.10.1 런타임 의미론: 평가

ImportCall : import ( AssignmentExpression ,opt )
  1. EvaluateImportCall(AssignmentExpression)을 반환한다.
ImportCall : import ( AssignmentExpression , AssignmentExpression ,opt )
  1. EvaluateImportCall(첫 번째 AssignmentExpression, 두 번째 AssignmentExpression)을 반환한다.

13.3.10.2 EvaluateImportCall ( specifierExpression [ , optionsExpression ] )

추상 연산 EvaluateImportCall은 specifierExpression (파스 노드)와 선택적 인수 optionsExpression (파스 노드)를 인수로 받고, 프로미스가 담긴 정상 완료(normal completion) 또는 비정상 완료(abrupt completion)를 반환한다. 호출 시 다음 단계를 수행한다:

  1. referrerGetActiveScriptOrModule()로 한다.
  2. referrernull이면 referrer현재 Realm Record로 설정한다.
  3. specifierRef를 ? Evaluation of specifierExpression의 결과로 한다.
  4. specifier를 ? GetValue(specifierRef)로 한다.
  5. optionsExpression이 존재하면,
    1. optionsRef를 ? Evaluation of optionsExpression의 결과로 한다.
    2. options를 ? GetValue(optionsRef)로 한다.
  6. 그 외에는,
    1. optionsundefined로 한다.
  7. promiseCapability를 ! NewPromiseCapability(%Promise%)로 한다.
  8. specifierStringCompletion(ToString(specifier))로 한다.
  9. IfAbruptRejectPromise(specifierString, promiseCapability)를 수행한다.
  10. attributes를 새로운 빈 리스트로 한다.
  11. optionsundefined가 아니면,
    1. options객체가 아니면,
      1. Call(promiseCapability.[[Reject]], undefined, « 새로 생성된 TypeError 객체 »)를 수행한다.
      2. promiseCapability.[[Promise]]를 반환한다.
    2. attributesObjCompletion(Get(options, "with"))로 한다.
    3. IfAbruptRejectPromise(attributesObj, promiseCapability)를 수행한다.
    4. attributesObj가 undefined가 아니면,
      1. attributesObj가 객체가 아니면,
        1. Call(promiseCapability.[[Reject]], undefined, « 새로 생성된 TypeError 객체 »)를 수행한다.
        2. promiseCapability.[[Promise]]를 반환한다.
      2. entriesCompletion(EnumerableOwnProperties(attributesObj, key+value))로 한다.
      3. IfAbruptRejectPromise(entries, promiseCapability)를 수행한다.
      4. entries의 각 요소 entry에 대해,
        1. key를 ! Get(entry, "0")로 한다.
        2. value를 ! Get(entry, "1")로 한다.
        3. key가 문자열이면,
          1. value가 문자열이 아니면,
            1. Call(promiseCapability.[[Reject]], undefined, « 새로 생성된 TypeError 객체 »)를 수행한다.
            2. promiseCapability.[[Promise]]를 반환한다.
          2. ImportAttribute Record { [[Key]]: key, [[Value]]: value }를 attributes에 추가한다.
    5. AllImportAttributesSupported(attributes) 가 false라면,
      1. Call(promiseCapability.[[Reject]], undefined, « 새로 생성된 TypeError 객체 »)를 수행한다.
      2. promiseCapability.[[Promise]]를 반환한다.
    6. attributes를 각 [[Key]] 필드 값을 UTF-16 코드 유닛의 시퀀스로 취급하여 사전식(lexicographic)으로 정렬한다. 참고: 이 정렬은 호스트가 속성의 열거 순서에 따라 동작을 바꾸지 못하도록 금지하는 목적에서만 관찰 가능하다.
  12. moduleRequestModuleRequest Record { [[Specifier]]: specifierString, [[Attributes]]: attributes }로 한다.
  13. HostLoadImportedModule(referrer, moduleRequest, empty, promiseCapability)를 수행한다.
  14. promiseCapability.[[Promise]]를 반환한다.

13.3.10.3 ContinueDynamicImport ( promiseCapability, moduleCompletion )

추상 연산 ContinueDynamicImport는 promiseCapability (PromiseCapability Record), moduleCompletion (정상 완료(normal completion)가 담긴 Module Record 또는 throw completion)를 인수로 받고 unused를 반환한다. 이는 import() 호출로 시작된 동적 import의 처리를 완료하며, 그 호출이 반환한 프로미스를 적절히 resolve 또는 reject 한다. 호출 시 다음 단계를 수행한다:

  1. moduleCompletion비정상 완료(abrupt completion)라면,
    1. Call(promiseCapability.[[Reject]], undefined, « moduleCompletion.[[Value]] »)를 수행한다.
    2. unused를 반환한다.
  2. modulemoduleCompletion.[[Value]]로 한다.
  3. loadPromisemodule.LoadRequestedModules()로 한다.
  4. rejectedClosure를 매개변수 (reason)를 가지며 promiseCapability를 캡처하고, 호출 시 다음 단계를 수행하는 새로운 Abstract Closure로 한다:
    1. Call(promiseCapability.[[Reject]], undefined, « reason »)를 수행한다.
    2. NormalCompletion(undefined)을 반환한다.
  5. onRejectedCreateBuiltinFunction(rejectedClosure, 1, "", « »)로 한다.
  6. linkAndEvaluateClosure를 매개변수 없이 module, promiseCapability, onRejected를 캡처하고, 호출 시 다음 단계를 수행하는 새로운 Abstract Closure로 한다:
    1. linkCompletion(module.Link())로 한다.
    2. link비정상 완료(abrupt completion)라면,
      1. Call(promiseCapability.[[Reject]], undefined, « link.[[Value]] »)를 수행한다.
      2. NormalCompletion(undefined)을 반환한다.
    3. evaluatePromisemodule.Evaluate()로 한다.
    4. fulfilledClosure를 매개변수 없이 modulepromiseCapability를 캡처하고, 호출 시 다음 단계를 수행하는 새로운 Abstract Closure로 한다:
      1. namespaceGetModuleNamespace(module)로 한다.
      2. Call(promiseCapability.[[Resolve]], undefined, « namespace »)를 수행한다.
      3. NormalCompletion(undefined)을 반환한다.
    5. onFulfilledCreateBuiltinFunction(fulfilledClosure, 0, "", « »)로 한다.
    6. PerformPromiseThen(evaluatePromise, onFulfilled, onRejected)를 수행한다.
    7. unused를 반환한다.
  7. linkAndEvaluateCreateBuiltinFunction(linkAndEvaluateClosure, 0, "", « »)로 한다.
  8. PerformPromiseThen(loadPromise, linkAndEvaluate, onRejected)를 수행한다.
  9. unused를 반환한다.

13.3.11 태그드 템플릿

참고

태그드 템플릿은 함수 호출로, 호출의 인수들은 TemplateLiteral (13.2.8)에서 유도된다. 실제 인수에는 템플릿 객체(13.2.8.4)와 TemplateLiteral 내에 포함된 표현식들을 평가하여 얻은 값들이 포함된다.

13.3.11.1 런타임 의미론: 평가

MemberExpression : MemberExpression TemplateLiteral
  1. tagRef를 ? Evaluation of MemberExpression의 결과로 한다.
  2. tagFunc를 ? GetValue(tagRef)로 한다.
  3. thisCall을 this MemberExpression로 한다.
  4. tailCallIsInTailPosition(thisCall)로 한다.
  5. EvaluateCall(tagFunc, tagRef, TemplateLiteral, tailCall)의 결과를 반환한다.
CallExpression : CallExpression TemplateLiteral
  1. tagRef를 ? Evaluation of CallExpression의 결과로 한다.
  2. tagFunc를 ? GetValue(tagRef)로 한다.
  3. thisCall을 this CallExpression로 한다.
  4. tailCallIsInTailPosition(thisCall)로 한다.
  5. EvaluateCall(tagFunc, tagRef, TemplateLiteral, tailCall)의 결과를 반환한다.

13.3.12 메타 프로퍼티

13.3.12.1 런타임 의미론: 평가

NewTarget : new . target
  1. GetNewTarget()를 반환한다.
ImportMeta : import . meta
  1. moduleGetActiveScriptOrModule()로 한다.
  2. Assert: module소스 텍스트 모듈 레코드(Source Text Module Record)이다.
  3. importMetamodule.[[ImportMeta]]로 한다.
  4. importMetaempty이면,
    1. importMetaOrdinaryObjectCreate(null)로 설정한다.
    2. importMetaValuesHostGetImportMetaProperties(module)로 한다.
    3. importMetaValues의 각 Record { [[Key]], [[Value]] } p에 대해,
      1. CreateDataPropertyOrThrow(importMeta, p.[[Key]], p.[[Value]])를 수행한다.
    4. HostFinalizeImportMeta(importMeta, module)를 수행한다.
    5. module.[[ImportMeta]]importMeta로 설정한다.
    6. importMeta를 반환한다.
  5. 그 외에는,
    1. Assert: importMeta 객체이다.
    2. importMeta를 반환한다.

13.3.12.1.1 HostGetImportMetaProperties ( moduleRecord )

호스트 정의 추상 연산 HostGetImportMetaProperties는 moduleRecord (모듈 레코드(Module Record))를 인수로 받고, 리스트(List)를 반환한다. 리스트는 Record들로 구성되며, 각 Record는 [[Key]] (프로퍼티 키)와 [[Value]] (ECMAScript 언어 값) 필드를 가진다. 이 연산은 호스트import.meta에서 반환되는 객체에 프로퍼티 키와 값을 제공할 수 있도록 한다.

HostGetImportMetaProperties의 기본 구현은 새로운 빈 리스트(List)를 반환한다.

13.3.12.1.2 HostFinalizeImportMeta ( importMeta, moduleRecord )

호스트 정의 추상 연산 HostFinalizeImportMeta는 importMeta (객체)와 moduleRecord (모듈 레코드(Module Record))를 인수로 받고 unused를 반환한다. 이 연산은 호스트import.meta에서 반환되는 객체를 ECMAScript 코드에 노출하기 전에 특별한 처리를 할 수 있도록 한다.

대부분의 호스트HostGetImportMetaProperties만 정의하고, HostFinalizeImportMeta는 기본 동작을 사용하면 된다. 그러나 HostFinalizeImportMeta는 호스트가 객체를 직접 조작해야 할 경우를 위한 "탈출구"를 제공한다.

HostFinalizeImportMeta의 기본 구현은 unused를 반환한다.

13.4 증감식

구문

UpdateExpression[Yield, Await] : LeftHandSideExpression[?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await] [여기에 LineTerminator 없음] ++ LeftHandSideExpression[?Yield, ?Await] [여기에 LineTerminator 없음] -- ++ UnaryExpression[?Yield, ?Await] -- UnaryExpression[?Yield, ?Await]

13.4.1 정적 의미론: 초기 에러

UpdateExpression : LeftHandSideExpression ++ LeftHandSideExpression -- UpdateExpression : ++ UnaryExpression -- UnaryExpression

13.4.2 후위 증가 연산자

13.4.2.1 런타임 의미론: 평가

UpdateExpression : LeftHandSideExpression ++
  1. lhs를 ? Evaluation of LeftHandSideExpression의 결과로 한다.
  2. LeftHandSideExpressionAssignmentTargetTypeweb-compat이면, ReferenceError 예외를 발생시킨다.
  3. oldValue를 ? ToNumeric(? GetValue(lhs))로 한다.
  4. oldValueNumber이면,
    1. newValueNumber::add(oldValue, 1𝔽)로 한다.
  5. 그 외에는,
    1. Assert: oldValueBigInt이다.
    2. newValueBigInt::add(oldValue, 1)로 한다.
  6. PutValue(lhs, newValue)를 수행한다.
  7. oldValue를 반환한다.

13.4.3 후위 감소 연산자

13.4.3.1 런타임 의미론: 평가

UpdateExpression : LeftHandSideExpression --
  1. lhs를 ? Evaluation of LeftHandSideExpression의 결과로 한다.
  2. LeftHandSideExpressionAssignmentTargetTypeweb-compat이면, ReferenceError 예외를 발생시킨다.
  3. oldValue를 ? ToNumeric(? GetValue(lhs))로 한다.
  4. oldValueNumber이면,
    1. newValueNumber::subtract(oldValue, 1𝔽)로 한다.
  5. 그 외에는,
    1. Assert: oldValueBigInt이다.
    2. newValueBigInt::subtract(oldValue, 1)로 한다.
  6. PutValue(lhs, newValue)를 수행한다.
  7. oldValue를 반환한다.

13.4.4 전위 증가 연산자

13.4.4.1 런타임 의미론: 평가

UpdateExpression : ++ UnaryExpression
  1. expr를 ? Evaluation of UnaryExpression의 결과로 한다.
  2. UnaryExpressionAssignmentTargetTypeweb-compat이면, ReferenceError 예외를 발생시킨다.
  3. oldValue를 ? ToNumeric(? GetValue(expr))로 한다.
  4. oldValueNumber이면,
    1. newValueNumber::add(oldValue, 1𝔽)로 한다.
  5. 그 외에는,
    1. Assert: oldValueBigInt이다.
    2. newValueBigInt::add(oldValue, 1)로 한다.
  6. PutValue(expr, newValue)를 수행한다.
  7. newValue를 반환한다.

13.4.5 전위 감소 연산자

13.4.5.1 런타임 의미론: 평가

UpdateExpression : -- UnaryExpression
  1. expr를 ? Evaluation of UnaryExpression의 결과로 한다.
  2. UnaryExpressionAssignmentTargetTypeweb-compat이면, ReferenceError 예외를 발생시킨다.
  3. oldValue를 ? ToNumeric(? GetValue(expr))로 한다.
  4. oldValueNumber이면,
    1. newValueNumber::subtract(oldValue, 1𝔽)로 한다.
  5. 그 외에는,
    1. Assert: oldValueBigInt이다.
    2. newValueBigInt::subtract(oldValue, 1)로 한다.
  6. PutValue(expr, newValue)를 수행한다.
  7. newValue를 반환한다.

13.5 단항 연산자

구문

UnaryExpression[Yield, Await] : UpdateExpression[?Yield, ?Await] delete UnaryExpression[?Yield, ?Await] void UnaryExpression[?Yield, ?Await] typeof UnaryExpression[?Yield, ?Await] + UnaryExpression[?Yield, ?Await] - UnaryExpression[?Yield, ?Await] ~ UnaryExpression[?Yield, ?Await] ! UnaryExpression[?Yield, ?Await] [+Await] AwaitExpression[?Yield]

13.5.1 delete 연산자

13.5.1.1 정적 의미론: 초기 에러

UnaryExpression : delete UnaryExpression 참고

마지막 규칙은 delete (((foo)))와 같은 표현식이 첫 번째 규칙의 재귀적 적용으로 인해 초기 에러를 발생시킴을 의미한다.

13.5.1.2 런타임 의미론: 평가

UnaryExpression : delete UnaryExpression
  1. ref를 ? Evaluation of UnaryExpression의 결과로 한다.
  2. refReference Record가 아니면, true를 반환한다.
  3. IsUnresolvableReference(ref) 가 true이면,
    1. Assert: ref.[[Strict]]false이다.
    2. true를 반환한다.
  4. IsPropertyReference(ref) 가 true이면,
    1. Assert: IsPrivateReference(ref) 가 false이다.
    2. IsSuperReference(ref) 가 true이면, ReferenceError 예외를 발생시킨다.
    3. baseObj를 ? ToObject(ref.[[Base]])로 한다.
    4. ref.[[ReferencedName]]프로퍼티 키가 아니면,
      1. ref.[[ReferencedName]]를 ? ToPropertyKey(ref.[[ReferencedName]])로 설정한다.
    5. deleteStatus를 ? baseObj.[[Delete]](ref.[[ReferencedName]])로 한다.
    6. deleteStatusfalse이고 ref.[[Strict]]true이면, TypeError 예외를 발생시킨다.
    7. deleteStatus를 반환한다.
  5. 그 외에는,
    1. baseref.[[Base]]로 한다.
    2. Assert: baseEnvironment Record이다.
    3. base.DeleteBinding(ref.[[ReferencedName]])을 반환한다.
참고 1

delete 연산자가 strict mode 코드 내에서 등장하면, 그 UnaryExpression이 변수, 함수 인수, 또는 함수 이름에 대한 직접 참조인 경우 SyntaxError 예외가 발생한다. 또한, delete 연산자가 strict mode 코드 내에 있고 삭제 대상 프로퍼티의 속성이 { [[Configurable]]: false }(또는 삭제할 수 없는 경우)이면 TypeError 예외가 발생한다.

참고 2

4.c 단계에서 생성될 수 있는 객체는 위의 추상 연산과 일반 객체 [[Delete]] 내부 메서드 외부에서는 접근할 수 없다. 실제 구현에서는 실제로 객체를 생성하지 않을 수도 있다.

13.5.2 void 연산자

13.5.2.1 런타임 의미론: 평가

UnaryExpression : void UnaryExpression
  1. expr를 ? Evaluation of UnaryExpression의 결과로 한다.
  2. GetValue(expr)를 수행한다.
  3. undefined를 반환한다.
참고

GetValue는 그 값이 사용되지 않더라도 관찰 가능한 부작용이 있을 수 있으므로 반드시 호출되어야 한다.

13.5.3 typeof 연산자

13.5.3.1 런타임 의미론: 평가

UnaryExpression : typeof UnaryExpression
  1. val를 ? Evaluation of UnaryExpression의 결과로 한다.
  2. valReference Record이면,
    1. IsUnresolvableReference(val) 가 true이면 "undefined"를 반환한다.
  3. val를 ? GetValue(val)로 한다.
  4. valundefined이면 "undefined"를 반환한다.
  5. valnull이면 "object"를 반환한다.
  6. valString이면 "string"를 반환한다.
  7. valSymbol이면 "symbol"를 반환한다.
  8. valBoolean이면 "boolean"를 반환한다.
  9. valNumber이면 "number"를 반환한다.
  10. valBigInt이면 "bigint"를 반환한다.
  11. Assert: val객체이다.
  12. 참고: 이 단계는 B.3.6.3 절에서 대체된다.
  13. val[[Call]] 내부 메서드가 있으면 "function"를 반환한다.
  14. "object"를 반환한다.

13.5.4 단항 + 연산자

참고

단항 + 연산자는 피연산자를 Number 타입으로 변환한다.

13.5.4.1 런타임 의미론: 평가

UnaryExpression : + UnaryExpression
  1. expr를 ? Evaluation of UnaryExpression의 결과로 한다.
  2. ToNumber(? GetValue(expr))를 반환한다.

13.5.5 단항 - 연산자

참고

단항 - 연산자는 피연산자를 숫자 값으로 변환한 뒤 부호를 반전시킨다. +0𝔽의 부호를 반전하면 -0𝔽이 되고, -0𝔽의 부호를 반전하면 +0𝔽이 된다.

13.5.5.1 런타임 의미론: 평가

UnaryExpression : - UnaryExpression
  1. expr를 ? Evaluation of UnaryExpression의 결과로 한다.
  2. oldValue를 ? ToNumeric(? GetValue(expr))로 한다.
  3. oldValueNumber이면,
    1. Number::unaryMinus(oldValue)를 반환한다.
  4. 그 외에는,
    1. Assert: oldValueBigInt이다.
    2. BigInt::unaryMinus(oldValue)를 반환한다.

13.5.6 비트 NOT 연산자 (~)

13.5.6.1 런타임 의미론: 평가

UnaryExpression : ~ UnaryExpression
  1. expr를 ? Evaluation of UnaryExpression의 결과로 한다.
  2. oldValue를 ? ToNumeric(? GetValue(expr))로 한다.
  3. oldValueNumber이면,
    1. Number::bitwiseNOT(oldValue)를 반환한다.
  4. 그 외에는,
    1. Assert: oldValueBigInt이다.
    2. BigInt::bitwiseNOT(oldValue)를 반환한다.

13.5.7 논리 NOT 연산자 (!)

13.5.7.1 런타임 의미론: 평가

UnaryExpression : ! UnaryExpression
  1. expr를 ? Evaluation of UnaryExpression의 결과로 한다.
  2. oldValueToBoolean(? GetValue(expr))로 한다.
  3. oldValuetrue이면 false를 반환한다.
  4. true를 반환한다.

13.6 거듭제곱 연산자

구문

ExponentiationExpression[Yield, Await] : UnaryExpression[?Yield, ?Await] UpdateExpression[?Yield, ?Await] ** ExponentiationExpression[?Yield, ?Await]

13.6.1 런타임 의미론: 평가

ExponentiationExpression : UpdateExpression ** ExponentiationExpression
  1. EvaluateStringOrNumericBinaryExpression(UpdateExpression, **, ExponentiationExpression)를 반환한다.

13.7 곱셈 연산자

구문

MultiplicativeExpression[Yield, Await] : ExponentiationExpression[?Yield, ?Await] MultiplicativeExpression[?Yield, ?Await] MultiplicativeOperator ExponentiationExpression[?Yield, ?Await] MultiplicativeOperator : one of * / % 참고
  • * 연산자는 곱셈을 수행하여 피연산자의 곱을 생성한다.
  • / 연산자는 나눗셈을 수행하여 피연산자의 몫을 생성한다.
  • % 연산자는 암묵적 나눗셈에서 피연산자의 나머지를 반환한다.

13.7.1 런타임 의미론: 평가

MultiplicativeExpression : MultiplicativeExpression MultiplicativeOperator ExponentiationExpression
  1. opText소스 텍스트에서 일치하는 MultiplicativeOperator의 값으로 한다.
  2. EvaluateStringOrNumericBinaryExpression(MultiplicativeExpression, opText, ExponentiationExpression)를 반환한다.

13.8 덧셈 연산자

구문

AdditiveExpression[Yield, Await] : MultiplicativeExpression[?Yield, ?Await] AdditiveExpression[?Yield, ?Await] + MultiplicativeExpression[?Yield, ?Await] AdditiveExpression[?Yield, ?Await] - MultiplicativeExpression[?Yield, ?Await]

13.8.1 덧셈 연산자 (+)

참고

덧셈 연산자는 문자열 연결 또는 숫자 덧셈을 수행한다.

13.8.1.1 런타임 의미론: 평가

AdditiveExpression : AdditiveExpression + MultiplicativeExpression
  1. EvaluateStringOrNumericBinaryExpression(AdditiveExpression, +, MultiplicativeExpression)를 반환한다.

13.8.2 뺄셈 연산자 (-)

참고

- 연산자는 뺄셈을 수행하여 피연산자의 차를 생성한다.

13.8.2.1 런타임 의미론: 평가

AdditiveExpression : AdditiveExpression - MultiplicativeExpression
  1. EvaluateStringOrNumericBinaryExpression(AdditiveExpression, -, MultiplicativeExpression)를 반환한다.

13.9 비트 시프트 연산자

구문

ShiftExpression[Yield, Await] : AdditiveExpression[?Yield, ?Await] ShiftExpression[?Yield, ?Await] << AdditiveExpression[?Yield, ?Await] ShiftExpression[?Yield, ?Await] >> AdditiveExpression[?Yield, ?Await] ShiftExpression[?Yield, ?Await] >>> AdditiveExpression[?Yield, ?Await]

13.9.1 왼쪽 시프트 연산자 (<<)

참고

왼쪽 피연산자를 오른쪽 피연산자가 지정한 만큼 비트 단위로 왼쪽으로 시프트(이동)한다.

13.9.1.1 런타임 의미론: 평가

ShiftExpression : ShiftExpression << AdditiveExpression
  1. EvaluateStringOrNumericBinaryExpression(ShiftExpression, <<, AdditiveExpression)를 반환한다.

13.9.2 부호 있는 오른쪽 시프트 연산자 (>>)

참고

왼쪽 피연산자를 오른쪽 피연산자가 지정한 만큼 부호 비트를 채우며 비트 단위로 오른쪽으로 시프트(이동)한다.

13.9.2.1 런타임 의미론: 평가

ShiftExpression : ShiftExpression >> AdditiveExpression
  1. EvaluateStringOrNumericBinaryExpression(ShiftExpression, >>, AdditiveExpression)를 반환한다.

13.9.3 부호 없는 오른쪽 시프트 연산자 (>>> )

참고

왼쪽 피연산자를 오른쪽 피연산자가 지정한 만큼 0으로 채우며 비트 단위로 오른쪽으로 시프트(이동)한다.

13.9.3.1 런타임 의미론: 평가

ShiftExpression : ShiftExpression >>> AdditiveExpression
  1. EvaluateStringOrNumericBinaryExpression(ShiftExpression, >>>, AdditiveExpression)를 반환한다.

13.10 관계 연산자

참고 1

관계 연산자를 평가한 결과는 항상 Boolean 타입이며, 피연산자 간의 관계가 연산자가 지정한 관계를 만족하는지 여부를 나타낸다.

구문

RelationalExpression[In, Yield, Await] : ShiftExpression[?Yield, ?Await] RelationalExpression[?In, ?Yield, ?Await] < ShiftExpression[?Yield, ?Await] RelationalExpression[?In, ?Yield, ?Await] > ShiftExpression[?Yield, ?Await] RelationalExpression[?In, ?Yield, ?Await] <= ShiftExpression[?Yield, ?Await] RelationalExpression[?In, ?Yield, ?Await] >= ShiftExpression[?Yield, ?Await] RelationalExpression[?In, ?Yield, ?Await] instanceof ShiftExpression[?Yield, ?Await] [+In] RelationalExpression[+In, ?Yield, ?Await] in ShiftExpression[?Yield, ?Await] [+In] PrivateIdentifier in ShiftExpression[?Yield, ?Await] 참고 2

[In] 문법 매개변수는 관계식에서 in 연산자와 for 문에서의 in 연산자를 혼동하지 않도록 필요하다.

13.10.1 런타임 의미론: 평가

RelationalExpression : RelationalExpression < ShiftExpression
  1. lRef를 ? Evaluation of RelationalExpression의 결과로 한다.
  2. lVal를 ? GetValue(lRef)로 한다.
  3. rRef를 ? Evaluation of ShiftExpression의 결과로 한다.
  4. rVal를 ? GetValue(rRef)로 한다.
  5. r를 ? IsLessThan(lVal, rVal, true)로 한다.
  6. rundefined이면 false를, 아니면 r를 반환한다.
RelationalExpression : RelationalExpression > ShiftExpression
  1. lRef를 ? Evaluation of RelationalExpression의 결과로 한다.
  2. lVal를 ? GetValue(lRef)로 한다.
  3. rRef를 ? Evaluation of ShiftExpression의 결과로 한다.
  4. rVal를 ? GetValue(rRef)로 한다.
  5. r를 ? IsLessThan(rVal, lVal, false)로 한다.
  6. rundefined이면 false를, 아니면 r를 반환한다.
RelationalExpression : RelationalExpression <= ShiftExpression
  1. lRef를 ? Evaluation of RelationalExpression의 결과로 한다.
  2. lVal를 ? GetValue(lRef)로 한다.
  3. rRef를 ? Evaluation of ShiftExpression의 결과로 한다.
  4. rVal를 ? GetValue(rRef)로 한다.
  5. r를 ? IsLessThan(rVal, lVal, false)로 한다.
  6. rtrue 또는 undefined이면 false를, 아니면 true를 반환한다.
RelationalExpression : RelationalExpression >= ShiftExpression
  1. lRef를 ? Evaluation of RelationalExpression의 결과로 한다.
  2. lVal를 ? GetValue(lRef)로 한다.
  3. rRef를 ? Evaluation of ShiftExpression의 결과로 한다.
  4. rVal를 ? GetValue(rRef)로 한다.
  5. r를 ? IsLessThan(lVal, rVal, true)로 한다.
  6. rtrue 또는 undefined이면 false를, 아니면 true를 반환한다.
RelationalExpression : RelationalExpression instanceof ShiftExpression
  1. lRef를 ? Evaluation of RelationalExpression의 결과로 한다.
  2. lVal를 ? GetValue(lRef)로 한다.
  3. rRef를 ? Evaluation of ShiftExpression의 결과로 한다.
  4. rVal를 ? GetValue(rRef)로 한다.
  5. InstanceofOperator(lVal, rVal)를 반환한다.
RelationalExpression : RelationalExpression in ShiftExpression
  1. lRef를 ? Evaluation of RelationalExpression의 결과로 한다.
  2. lVal를 ? GetValue(lRef)로 한다.
  3. rRef를 ? Evaluation of ShiftExpression의 결과로 한다.
  4. rVal를 ? GetValue(rRef)로 한다.
  5. rVal객체가 아니면, TypeError 예외를 throw한다.
  6. HasProperty(rVal, ? ToPropertyKey(lVal))를 반환한다.
RelationalExpression : PrivateIdentifier in ShiftExpression
  1. privateIdentifierStringValue of PrivateIdentifier로 한다.
  2. rRef를 ? Evaluation of ShiftExpression의 결과로 한다.
  3. rVal를 ? GetValue(rRef)로 한다.
  4. rVal객체가 아니면, TypeError 예외를 throw한다.
  5. privateEnv실행 중인 실행 컨텍스트(running execution context)의 PrivateEnvironment로 한다.
  6. Assert: privateEnvnull이 아니다.
  7. privateNameResolvePrivateIdentifier(privateEnv, privateIdentifier)로 한다.
  8. PrivateElementFind(rVal, privateName)이 empty가 아니면 true를 반환한다.
  9. false를 반환한다.

13.10.2 InstanceofOperator ( V, target )

추상 연산 InstanceofOperator는 V (ECMAScript 언어 값)와 target (ECMAScript 언어 값)을 인수로 받고, Boolean이 담긴 정상 완료 또는 throw completion를 반환한다. 이 연산은 target%Symbol.hasInstance% 메서드를 참조하거나, 없을 경우 target"prototype" 프로퍼티 값이 V의 프로토타입 체인에 존재하는지를 확인하여 Vtarget의 인스턴스인지 판별한다. 호출 시 다음 단계를 수행한다:

  1. target객체가 아니면, TypeError 예외를 throw한다.
  2. instOfHandler를 ? GetMethod(target, %Symbol.hasInstance%)로 한다.
  3. instOfHandlerundefined가 아니면,
    1. ToBoolean(? Call(instOfHandler, target, « V »))를 반환한다.
  4. IsCallable(target)이 false이면 TypeError 예외를 throw한다.
  5. OrdinaryHasInstance(target, V)를 반환한다.
참고

단계 45%Symbol.hasInstance% 메서드를 사용하지 않는 이전 ECMAScript 판과의 호환성을 제공한다. 객체가 %Symbol.hasInstance%를 정의하거나 상속하지 않은 경우 기본 instanceof 의미론을 사용한다.

13.11 동등 연산자

참고

동등 연산자를 평가한 결과는 항상 Boolean 타입이며, 연산자가 지칭하는 관계가 두 피연산자 사이에 성립하는지 여부를 나타낸다.

구문

EqualityExpression[In, Yield, Await] : RelationalExpression[?In, ?Yield, ?Await] EqualityExpression[?In, ?Yield, ?Await] == RelationalExpression[?In, ?Yield, ?Await] EqualityExpression[?In, ?Yield, ?Await] != RelationalExpression[?In, ?Yield, ?Await] EqualityExpression[?In, ?Yield, ?Await] === RelationalExpression[?In, ?Yield, ?Await] EqualityExpression[?In, ?Yield, ?Await] !== RelationalExpression[?In, ?Yield, ?Await]

13.11.1 런타임 의미론: 평가

EqualityExpression : EqualityExpression == RelationalExpression
  1. lRef를 ? Evaluation of EqualityExpression의 결과로 한다.
  2. lVal를 ? GetValue(lRef)로 한다.
  3. rRef를 ? Evaluation of RelationalExpression의 결과로 한다.
  4. rVal를 ? GetValue(rRef)로 한다.
  5. IsLooselyEqual(rVal, lVal)을 반환한다.
EqualityExpression : EqualityExpression != RelationalExpression
  1. lRef를 ? Evaluation of EqualityExpression의 결과로 한다.
  2. lVal를 ? GetValue(lRef)로 한다.
  3. rRef를 ? Evaluation of RelationalExpression의 결과로 한다.
  4. rVal를 ? GetValue(rRef)로 한다.
  5. r를 ? IsLooselyEqual(rVal, lVal)로 한다.
  6. rtrue이면 false를, 아니면 true를 반환한다.
EqualityExpression : EqualityExpression === RelationalExpression
  1. lRef를 ? Evaluation of EqualityExpression의 결과로 한다.
  2. lVal를 ? GetValue(lRef)로 한다.
  3. rRef를 ? Evaluation of RelationalExpression의 결과로 한다.
  4. rVal를 ? GetValue(rRef)로 한다.
  5. IsStrictlyEqual(rVal, lVal)을 반환한다.
EqualityExpression : EqualityExpression !== RelationalExpression
  1. lRef를 ? Evaluation of EqualityExpression의 결과로 한다.
  2. lVal를 ? GetValue(lRef)로 한다.
  3. rRef를 ? Evaluation of RelationalExpression의 결과로 한다.
  4. rVal를 ? GetValue(rRef)로 한다.
  5. rIsStrictlyEqual(rVal, lVal)로 한다.
  6. rtrue이면 false를, 아니면 true를 반환한다.
참고 1

위의 동등 연산 정의에 따르면:

  • 문자열 비교를 강제하려면: `${a}` == `${b}`를 사용한다.
  • 숫자 비교를 강제하려면: +a == +b를 사용한다.
  • 불리언 비교를 강제하려면: !a == !b를 사용한다.
참고 2

동등 연산자는 다음 불변식을 유지한다:

  • A != B!(A == B)와 동치이다.
  • A == BB == A와 동치이나, AB의 평가 순서는 다를 수 있다.
참고 3

동등 연산자는 항상 추이적이지 않다. 예를 들어 동일한 문자열 값을 갖는 두 개의 서로 다른 String 객체가 있을 수 있다. 각 String 객체는 == 연산자에 의해 그 문자열 값과 동등하게 평가되지만, 두 String 객체끼리는 동등하지 않다. 예시:

  • new String("a") == "a""a" == new String("a")는 모두 true이다.
  • new String("a") == new String("a")false이다.
참고 4

문자열의 비교는 코드 유닛 값 시퀀스에 대한 단순 동등성 테스트를 사용한다. 유니코드 명세에 정의된 문자 또는 문자열 동등성 및 정렬 순서의 더 복잡한 의미론적 정의를 사용하지 않는다. 따라서 유니코드 표준에 따라 정규화된 문자열 값이라도 서로 다르다고 평가될 수 있다. 사실상 이 알고리즘은 두 문자열이 이미 정규화된 형태임을 전제로 한다.

13.12 이진 비트 연산자

구문

BitwiseANDExpression[In, Yield, Await] : EqualityExpression[?In, ?Yield, ?Await] BitwiseANDExpression[?In, ?Yield, ?Await] & EqualityExpression[?In, ?Yield, ?Await] BitwiseXORExpression[In, Yield, Await] : BitwiseANDExpression[?In, ?Yield, ?Await] BitwiseXORExpression[?In, ?Yield, ?Await] ^ BitwiseANDExpression[?In, ?Yield, ?Await] BitwiseORExpression[In, Yield, Await] : BitwiseXORExpression[?In, ?Yield, ?Await] BitwiseORExpression[?In, ?Yield, ?Await] | BitwiseXORExpression[?In, ?Yield, ?Await]

13.12.1 런타임 의미론: 평가

BitwiseANDExpression : BitwiseANDExpression & EqualityExpression
  1. EvaluateStringOrNumericBinaryExpression(BitwiseANDExpression, &, EqualityExpression)를 반환한다.
BitwiseXORExpression : BitwiseXORExpression ^ BitwiseANDExpression
  1. EvaluateStringOrNumericBinaryExpression(BitwiseXORExpression, ^, BitwiseANDExpression)를 반환한다.
BitwiseORExpression : BitwiseORExpression | BitwiseXORExpression
  1. EvaluateStringOrNumericBinaryExpression(BitwiseORExpression, |, BitwiseXORExpression)를 반환한다.

13.13 이진 논리 연산자

구문

LogicalANDExpression[In, Yield, Await] : BitwiseORExpression[?In, ?Yield, ?Await] LogicalANDExpression[?In, ?Yield, ?Await] && BitwiseORExpression[?In, ?Yield, ?Await] LogicalORExpression[In, Yield, Await] : LogicalANDExpression[?In, ?Yield, ?Await] LogicalORExpression[?In, ?Yield, ?Await] || LogicalANDExpression[?In, ?Yield, ?Await] CoalesceExpression[In, Yield, Await] : CoalesceExpressionHead[?In, ?Yield, ?Await] ?? BitwiseORExpression[?In, ?Yield, ?Await] CoalesceExpressionHead[In, Yield, Await] : CoalesceExpression[?In, ?Yield, ?Await] BitwiseORExpression[?In, ?Yield, ?Await] ShortCircuitExpression[In, Yield, Await] : LogicalORExpression[?In, ?Yield, ?Await] CoalesceExpression[?In, ?Yield, ?Await] 참고

&& 또는 || 연산자가 생성하는 값은 반드시 Boolean 타입일 필요는 없다. 생성되는 값은 항상 두 피연산자 중 하나의 값이 된다.

13.13.1 런타임 의미론: 평가

LogicalANDExpression : LogicalANDExpression && BitwiseORExpression
  1. lRef를 ? Evaluation of LogicalANDExpression의 결과로 한다.
  2. lVal를 ? GetValue(lRef)로 한다.
  3. ToBoolean(lVal)이 false이면 lVal를 반환한다.
  4. rRef를 ? Evaluation of BitwiseORExpression의 결과로 한다.
  5. GetValue(rRef)를 반환한다.
LogicalORExpression : LogicalORExpression || LogicalANDExpression
  1. lRef를 ? Evaluation of LogicalORExpression의 결과로 한다.
  2. lVal를 ? GetValue(lRef)로 한다.
  3. ToBoolean(lVal)이 true이면 lVal를 반환한다.
  4. rRef를 ? Evaluation of LogicalANDExpression의 결과로 한다.
  5. GetValue(rRef)를 반환한다.
CoalesceExpression : CoalesceExpressionHead ?? BitwiseORExpression
  1. lRef를 ? Evaluation of CoalesceExpressionHead의 결과로 한다.
  2. lVal를 ? GetValue(lRef)로 한다.
  3. lValundefined 또는 null이면,
    1. rRef를 ? Evaluation of BitwiseORExpression의 결과로 한다.
    2. GetValue(rRef)를 반환한다.
  4. 그 외에는,
    1. lVal를 반환한다.

13.14 조건 연산자 (? :)

구문

ConditionalExpression[In, Yield, Await] : ShortCircuitExpression[?In, ?Yield, ?Await] ShortCircuitExpression[?In, ?Yield, ?Await] ? AssignmentExpression[+In, ?Yield, ?Await] : AssignmentExpression[?In, ?Yield, ?Await] 참고

ECMAScript에서 ConditionalExpression의 문법은 C와 Java와 약간 다릅니다. C와 Java는 두 번째 부분식에 Expression을 허용하지만, 세 번째 식은 ConditionalExpression으로 제한합니다. ECMAScript에서 이 차이를 둔 이유는 조건문의 어느 쪽 분기에도 할당식을 둘 수 있도록 하고, 가운데 식으로 콤마 식이 오는 혼란스럽고 거의 쓸모없는 경우를 없애기 위함입니다.

13.14.1 런타임 의미론: 평가

ConditionalExpression : ShortCircuitExpression ? AssignmentExpression : AssignmentExpression
  1. lRef를 ? Evaluation of ShortCircuitExpression의 결과로 한다.
  2. lValToBoolean(? GetValue(lRef))로 한다.
  3. lValtrue이면,
    1. trueRef를 ? Evaluation of 첫 번째 AssignmentExpression의 결과로 한다.
    2. GetValue(trueRef)를 반환한다.
  4. 그 외에는,
    1. falseRef를 ? Evaluation of 두 번째 AssignmentExpression의 결과로 한다.
    2. GetValue(falseRef)를 반환한다.

13.15 할당 연산자

구문

AssignmentExpression[In, Yield, Await] : ConditionalExpression[?In, ?Yield, ?Await] [+Yield] YieldExpression[?In, ?Await] ArrowFunction[?In, ?Yield, ?Await] AsyncArrowFunction[?In, ?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await] = AssignmentExpression[?In, ?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await] AssignmentOperator AssignmentExpression[?In, ?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await] &&= AssignmentExpression[?In, ?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await] ||= AssignmentExpression[?In, ?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await] ??= AssignmentExpression[?In, ?Yield, ?Await] AssignmentOperator : one of *= /= %= += -= <<= >>= >>>= &= ^= |= **=

13.15.1 정적 의미론: 초기 에러

AssignmentExpression : LeftHandSideExpression = AssignmentExpression AssignmentExpression : LeftHandSideExpression AssignmentOperator AssignmentExpression AssignmentExpression : LeftHandSideExpression &&= AssignmentExpression LeftHandSideExpression ||= AssignmentExpression LeftHandSideExpression ??= AssignmentExpression

13.15.2 런타임 의미론: 평가

AssignmentExpression : LeftHandSideExpression = AssignmentExpression
  1. LeftHandSideExpressionObjectLiteral도 아니고 ArrayLiteral도 아니면,
    1. lRef를 ? Evaluation of LeftHandSideExpression의 결과로 한다.
    2. LeftHandSideExpressionAssignmentTargetTypeweb-compat이면 ReferenceError 예외를 throw한다.
    3. IsAnonymousFunctionDefinition(AssignmentExpression)이 true이고 IsIdentifierRef of LeftHandSideExpressiontrue이면,
      1. lhsStringValue of LeftHandSideExpression로 한다.
      2. rVal를 ? NamedEvaluation of AssignmentExpression with argument lhs로 한다.
    4. 그 외에는,
      1. rRef를 ? Evaluation of AssignmentExpression의 결과로 한다.
      2. rVal를 ? GetValue(rRef)로 한다.
    5. PutValue(lRef, rVal)를 수행한다.
    6. rVal를 반환한다.
  2. assignmentPatternAssignmentPattern으로 하며, 이는 커버(cover)되어야 하며 LeftHandSideExpression에 의해 포함된다.
  3. rRef를 ? Evaluation of AssignmentExpression의 결과로 한다.
  4. rVal를 ? GetValue(rRef)로 한다.
  5. DestructuringAssignmentEvaluation of assignmentPattern with argument rVal을 수행한다.
  6. rVal를 반환한다.
AssignmentExpression : LeftHandSideExpression AssignmentOperator AssignmentExpression
  1. lRef를 ? Evaluation of LeftHandSideExpression의 결과로 한다.
  2. LeftHandSideExpressionAssignmentTargetTypeweb-compat이면 ReferenceError 예외를 throw한다.
  3. lVal를 ? GetValue(lRef)로 한다.
  4. rRef를 ? Evaluation of AssignmentExpression의 결과로 한다.
  5. rVal를 ? GetValue(rRef)로 한다.
  6. assignmentOpText소스 텍스트에서 일치하는 AssignmentOperator의 값으로 한다.
  7. opText를 다음 표에서 assignmentOpText에 해당하는 유니코드 코드 포인트 시퀀스로 한다:
    assignmentOpText opText
    **= **
    *= *
    /= /
    %= %
    += +
    -= -
    <<= <<
    >>= >>
    >>>= >>>
    &= &
    ^= ^
    |= |
  8. r를 ? ApplyStringOrNumericBinaryOperator(lVal, opText, rVal)로 한다.
  9. PutValue(lRef, r)를 수행한다.
  10. r를 반환한다.
AssignmentExpression : LeftHandSideExpression &&= AssignmentExpression
  1. lRef를 ? Evaluation of LeftHandSideExpression의 결과로 한다.
  2. lVal를 ? GetValue(lRef)로 한다.
  3. ToBoolean(lVal)이 false이면 lVal를 반환한다.
  4. IsAnonymousFunctionDefinition(AssignmentExpression)이 true이고 IsIdentifierRef of LeftHandSideExpressiontrue이면,
    1. lhsStringValue of LeftHandSideExpression로 한다.
    2. rVal를 ? NamedEvaluation of AssignmentExpression with argument lhs로 한다.
  5. 그 외에는,
    1. rRef를 ? Evaluation of AssignmentExpression의 결과로 한다.
    2. rVal를 ? GetValue(rRef)로 한다.
  6. PutValue(lRef, rVal)를 수행한다.
  7. rVal를 반환한다.
AssignmentExpression : LeftHandSideExpression ||= AssignmentExpression
  1. lRef를 ? Evaluation of LeftHandSideExpression의 결과로 한다.
  2. lVal를 ? GetValue(lRef)로 한다.
  3. ToBoolean(lVal)이 true이면 lVal를 반환한다.
  4. IsAnonymousFunctionDefinition(AssignmentExpression)이 true이고 IsIdentifierRef of LeftHandSideExpressiontrue이면,
    1. lhsStringValue of LeftHandSideExpression로 한다.
    2. rVal를 ? NamedEvaluation of AssignmentExpression with argument lhs로 한다.
  5. 그 외에는,
    1. rRef를 ? Evaluation of AssignmentExpression의 결과로 한다.
    2. rVal를 ? GetValue(rRef)로 한다.
  6. PutValue(lRef, rVal)를 수행한다.
  7. rVal를 반환한다.
AssignmentExpression : LeftHandSideExpression ??= AssignmentExpression
  1. lRef를 ? Evaluation of LeftHandSideExpression의 결과로 한다.
  2. lVal를 ? GetValue(lRef)로 한다.
  3. lValundefined도 아니고 null도 아니면 lVal를 반환한다.
  4. IsAnonymousFunctionDefinition(AssignmentExpression)이 true이고 IsIdentifierRef of LeftHandSideExpressiontrue이면,
    1. lhsStringValue of LeftHandSideExpression로 한다.
    2. rVal를 ? NamedEvaluation of AssignmentExpression with argument lhs로 한다.
  5. 그 외에는,
    1. rRef를 ? Evaluation of AssignmentExpression의 결과로 한다.
    2. rVal를 ? GetValue(rRef)로 한다.
  6. PutValue(lRef, rVal)를 수행한다.
  7. rVal를 반환한다.
참고

이 표현식이 strict mode 코드 내에 있을 때, 1.e, 3, 2, 2, 2 단계의 lRef가 해결할 수 없는 참조라면 런타임 오류가 발생하며, ReferenceError 예외가 throw된다. 또한 9, 6, 6, 6 단계의 lRef데이터 프로퍼티로서 { [[Writable]]: false } 속성을 갖거나, 접근자 프로퍼티로서 { [[Set]]: undefined } 속성을 갖거나, IsExtensiblefalse를 반환하는 객체의 존재하지 않는 프로퍼티라면 TypeError 예외가 throw된다.

13.15.3 ApplyStringOrNumericBinaryOperator ( lVal, opText, rVal )

추상 연산 ApplyStringOrNumericBinaryOperator는 lVal (ECMAScript 언어 값), opText (**, *, /, %, +, -, <<, >>, >>>, &, ^, 또는 |), rVal (ECMAScript 언어 값)을 인수로 받으며, String, BigInt 또는 Number가 담긴 정상 완료 또는 throw completion를 반환한다. 호출 시 다음 단계를 수행한다:

  1. opText+이면,
    1. lPrim을 ? ToPrimitive(lVal)로 한다.
    2. rPrim을 ? ToPrimitive(rVal)로 한다.
    3. lPrimString이거나 rPrimString이면,
      1. lStr을 ? ToString(lPrim)로 한다.
      2. rStr을 ? ToString(rPrim)로 한다.
      3. lStrrStr문자열 연결(string-concatenation) 결과를 반환한다.
    4. lVallPrim으로 설정한다.
    5. rValrPrim으로 설정한다.
  2. NOTE: 이 시점에서 반드시 숫자 연산이어야 한다.
  3. lNum을 ? ToNumeric(lVal)로 한다.
  4. rNum을 ? ToNumeric(rVal)로 한다.
  5. SameType(lNum, rNum)이 false이면, TypeError 예외를 throw한다.
  6. lNumBigInt이면,
    1. opText**이면, ? BigInt::exponentiate(lNum, rNum)를 반환한다.
    2. opText/이면, ? BigInt::divide(lNum, rNum)를 반환한다.
    3. opText%이면, ? BigInt::remainder(lNum, rNum)를 반환한다.
    4. opText>>>이면, ? BigInt::unsignedRightShift(lNum, rNum)를 반환한다.
    5. operation을 아래 표에서 opText와 연관된 추상 연산으로 한다:
      opText operation
      * BigInt::multiply
      + BigInt::add
      - BigInt::subtract
      << BigInt::leftShift
      >> BigInt::signedRightShift
      & BigInt::bitwiseAND
      ^ BigInt::bitwiseXOR
      | BigInt::bitwiseOR
  7. 그 외에는,
    1. Assert: lNumNumber임을 보장한다.
    2. operation을 아래 표에서 opText와 연관된 추상 연산으로 한다:
      opText operation
      ** Number::exponentiate
      * Number::multiply
      / Number::divide
      % Number::remainder
      + Number::add
      - Number::subtract
      << Number::leftShift
      >> Number::signedRightShift
      >>> Number::unsignedRightShift
      & Number::bitwiseAND
      ^ Number::bitwiseXOR
      | Number::bitwiseOR
  8. operation(lNum, rNum)을 반환한다.
참고 1

단계 ToPrimitive의 호출에는 힌트가 제공되지 않는다(1.a, 1.b). 표준 객체(날짜 객체 제외)는 힌트가 없으면 number가 주어진 것처럼 동작하며, 날짜 객체는 string이 주어진 것처럼 동작한다. Exotic 객체는 힌트가 없을 때 다르게 동작할 수 있다.

참고 2

1.c 단계는 3 단계 및 IsLessThan 알고리즘과 달리 논리합(or) 연산을 사용한다.

13.15.4 EvaluateStringOrNumericBinaryExpression ( leftOperand, opText, rightOperand )

추상 연산 EvaluateStringOrNumericBinaryExpression는 leftOperand (파스 노드(Parse Node)), opText (유니코드 코드 포인트의 시퀀스), rightOperand (파스 노드(Parse Node))를 인수로 받고, String, BigInt, Number가 담긴 정상 완료(normal completion) 또는 비정상 완료(abrupt completion)를 반환한다. 호출 시 다음 단계를 수행한다:

  1. lRef를 ? Evaluation of leftOperand의 결과로 한다.
  2. lVal를 ? GetValue(lRef)로 한다.
  3. rRef를 ? Evaluation of rightOperand의 결과로 한다.
  4. rVal를 ? GetValue(rRef)로 한다.
  5. ApplyStringOrNumericBinaryOperator(lVal, opText, rVal)를 반환한다.

13.15.5 구조 분해 할당

보충 구문

다음의 생성식의 인스턴스 처리를 수행할 때
AssignmentExpression : LeftHandSideExpression = AssignmentExpression
LeftHandSideExpression의 해석은 다음 문법을 사용하여 정교화된다:

AssignmentPattern[Yield, Await] : ObjectAssignmentPattern[?Yield, ?Await] ArrayAssignmentPattern[?Yield, ?Await] ObjectAssignmentPattern[Yield, Await] : { } { AssignmentRestProperty[?Yield, ?Await] } { AssignmentPropertyList[?Yield, ?Await] } { AssignmentPropertyList[?Yield, ?Await] , AssignmentRestProperty[?Yield, ?Await]opt } ArrayAssignmentPattern[Yield, Await] : [ Elisionopt AssignmentRestElement[?Yield, ?Await]opt ] [ AssignmentElementList[?Yield, ?Await] ] [ AssignmentElementList[?Yield, ?Await] , Elisionopt AssignmentRestElement[?Yield, ?Await]opt ] AssignmentRestProperty[Yield, Await] : ... DestructuringAssignmentTarget[?Yield, ?Await] AssignmentPropertyList[Yield, Await] : AssignmentProperty[?Yield, ?Await] AssignmentPropertyList[?Yield, ?Await] , AssignmentProperty[?Yield, ?Await] AssignmentElementList[Yield, Await] : AssignmentElisionElement[?Yield, ?Await] AssignmentElementList[?Yield, ?Await] , AssignmentElisionElement[?Yield, ?Await] AssignmentElisionElement[Yield, Await] : Elisionopt AssignmentElement[?Yield, ?Await] AssignmentProperty[Yield, Await] : IdentifierReference[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt PropertyName[?Yield, ?Await] : AssignmentElement[?Yield, ?Await] AssignmentElement[Yield, Await] : DestructuringAssignmentTarget[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt AssignmentRestElement[Yield, Await] : ... DestructuringAssignmentTarget[?Yield, ?Await] DestructuringAssignmentTarget[Yield, Await] : LeftHandSideExpression[?Yield, ?Await]

13.15.5.1 정적 의미론: 초기 에러

AssignmentProperty : IdentifierReference Initializeropt AssignmentRestProperty : ... DestructuringAssignmentTarget DestructuringAssignmentTarget : LeftHandSideExpression

13.15.5.2 런타임 의미론: DestructuringAssignmentEvaluation

구문 지시 연산 DestructuringAssignmentEvaluation은 value (ECMAScript 언어 값)을 인수로 받아, 정상 완료 unused 또는 비정상 완료를 반환한다. 아래 생성식에 대해 조각별로 정의된다:

ObjectAssignmentPattern : { }
  1. RequireObjectCoercible(value)를 수행한다.
  2. unused를 반환한다.
ObjectAssignmentPattern : { AssignmentPropertyList } { AssignmentPropertyList , }
  1. RequireObjectCoercible(value)를 수행한다.
  2. PropertyDestructuringAssignmentEvaluation of AssignmentPropertyListvalue 인수를 넘겨 수행한다.
  3. unused를 반환한다.
ObjectAssignmentPattern : { AssignmentRestProperty }
  1. RequireObjectCoercible(value)를 수행한다.
  2. excludedNames를 비어 있는 새 List로 한다.
  3. RestDestructuringAssignmentEvaluation of AssignmentRestPropertyvalue, excludedNames 인수를 넘겨 수행한 결과를 반환한다.
ObjectAssignmentPattern : { AssignmentPropertyList , AssignmentRestProperty }
  1. RequireObjectCoercible(value)를 수행한다.
  2. excludedNames를 ? PropertyDestructuringAssignmentEvaluation of AssignmentPropertyListvalue 인수를 넘겨 수행한 결과로 한다.
  3. RestDestructuringAssignmentEvaluation of AssignmentRestPropertyvalue, excludedNames 인수를 넘겨 수행한 결과를 반환한다.
ArrayAssignmentPattern : [ ]
  1. iteratorRecord를 ? GetIterator(value, sync)로 한다.
  2. IteratorClose(iteratorRecord, NormalCompletion(unused))를 반환한다.
ArrayAssignmentPattern : [ Elision ]
  1. iteratorRecord를 ? GetIterator(value, sync)로 한다.
  2. resultCompletion(IteratorDestructuringAssignmentEvaluation of ElisioniteratorRecord 인수를 넘겨 수행한 결과)로 한다.
  3. iteratorRecord.[[Done]]false이면, ? IteratorClose(iteratorRecord, result)를 반환한다.
  4. result를 반환한다.
ArrayAssignmentPattern : [ Elisionopt AssignmentRestElement ]
  1. iteratorRecord를 ? GetIterator(value, sync)로 한다.
  2. Elision이 존재하면,
    1. statusCompletion(IteratorDestructuringAssignmentEvaluation of ElisioniteratorRecord 인수를 넘겨 수행한 결과)로 한다.
    2. status비정상 완료라면,
      1. Assert: iteratorRecord.[[Done]]true임을 보장한다.
      2. status를 반환한다.
  3. resultCompletion(IteratorDestructuringAssignmentEvaluation of AssignmentRestElementiteratorRecord 인수를 넘겨 수행한 결과)로 한다.
  4. iteratorRecord.[[Done]]false이면, ? IteratorClose(iteratorRecord, result)를 반환한다.
  5. result를 반환한다.
ArrayAssignmentPattern : [ AssignmentElementList ]
  1. iteratorRecord를 ? GetIterator(value, sync)로 한다.
  2. resultCompletion(IteratorDestructuringAssignmentEvaluation of AssignmentElementListiteratorRecord 인수를 넘겨 수행한 결과)로 한다.
  3. iteratorRecord.[[Done]]false이면, ? IteratorClose(iteratorRecord, result)를 반환한다.
  4. result를 반환한다.
ArrayAssignmentPattern : [ AssignmentElementList , Elisionopt AssignmentRestElementopt ]
  1. iteratorRecord를 ? GetIterator(value, sync)로 한다.
  2. statusCompletion(IteratorDestructuringAssignmentEvaluation of AssignmentElementListiteratorRecord 인수를 넘겨 수행한 결과)로 한다.
  3. status비정상 완료라면,
    1. iteratorRecord.[[Done]]false이면, ? IteratorClose(iteratorRecord, status)를 반환한다.
    2. status를 반환한다.
  4. Elision이 존재하면,
    1. statusCompletion(IteratorDestructuringAssignmentEvaluation of ElisioniteratorRecord 인수를 넘겨 수행한 결과)로 한다.
    2. status비정상 완료라면,
      1. Assert: iteratorRecord.[[Done]]true임을 보장한다.
      2. status를 반환한다.
  5. AssignmentRestElement이 존재하면,
    1. statusCompletion(IteratorDestructuringAssignmentEvaluation of AssignmentRestElementiteratorRecord 인수를 넘겨 수행한 결과)로 한다.
  6. iteratorRecord.[[Done]]false이면, ? IteratorClose(iteratorRecord, status)를 반환한다.
  7. status를 반환한다.

13.15.5.3 런타임 의미론: PropertyDestructuringAssignmentEvaluation

구문 지시 연산 PropertyDestructuringAssignmentEvaluation은 value (ECMAScript 언어 값)을 인수로 받고, 정상 완료(normal completion)List (모든 구조 분해된 프로퍼티 키의 리스트) 또는 비정상 완료(abrupt completion)를 반환한다. 아래 생성식에 대해 조각별로 정의된다:

AssignmentPropertyList : AssignmentPropertyList , AssignmentProperty
  1. propertyNames를 ? PropertyDestructuringAssignmentEvaluation of AssignmentPropertyListvalue 인수를 넘겨 수행한 결과로 한다.
  2. nextNames를 ? PropertyDestructuringAssignmentEvaluation of AssignmentPropertyvalue 인수를 넘겨 수행한 결과로 한다.
  3. propertyNamesnextNames리스트 연결(list-concatenation) 결과를 반환한다.
AssignmentProperty : IdentifierReference Initializeropt
  1. PStringValue of IdentifierReference로 한다.
  2. lRef를 ? ResolveBinding(P)로 한다.
  3. v를 ? GetV(value, P)로 한다.
  4. Initializer가 존재하고 vundefined이면,
    1. IsAnonymousFunctionDefinition(Initializer)이 true이면,
      1. v를 ? NamedEvaluation of InitializerP 인수를 넘겨 수행한 결과로 설정한다.
    2. 그 외에는,
      1. defaultValue를 ? Evaluation of Initializer 결과로 한다.
      2. v를 ? GetValue(defaultValue)로 한다.
  5. PutValue(lRef, v)를 수행한다.
  6. « P »를 반환한다.
AssignmentProperty : PropertyName : AssignmentElement
  1. name을 ? Evaluation of PropertyName로 한다.
  2. KeyedDestructuringAssignmentEvaluation of AssignmentElementvalue, name 인수를 넘겨 수행한다.
  3. « name »를 반환한다.

13.15.5.4 런타임 의미론: RestDestructuringAssignmentEvaluation

구문 지시 연산 RestDestructuringAssignmentEvaluation은 value (ECMAScript 언어 값)과 excludedNames (List 타입의 프로퍼티 키 리스트)를 인수로 받고, 정상 완료(normal completion) unused 또는 비정상 완료(abrupt completion)를 반환한다. 아래 생성식에 대해 조각별로 정의된다:

AssignmentRestProperty : ... DestructuringAssignmentTarget
  1. lRef를 ? Evaluation of DestructuringAssignmentTarget의 결과로 한다.
  2. restObjOrdinaryObjectCreate(%Object.prototype%)로 한다.
  3. CopyDataProperties(restObj, value, excludedNames)를 수행한다.
  4. PutValue(lRef, restObj)를 반환한다.

13.15.5.5 런타임 의미론: IteratorDestructuringAssignmentEvaluation

구문 지시 연산 IteratorDestructuringAssignmentEvaluation은 iteratorRecord (이터레이터 레코드)를 인수로 받고, 정상 완료(normal completion) unused 또는 비정상 완료(abrupt completion)를 반환한다. 아래 생성식에 대해 조각별로 정의된다:

AssignmentElementList : AssignmentElisionElement
  1. IteratorDestructuringAssignmentEvaluation of AssignmentElisionElementiteratorRecord 인수를 넘겨 수행한 결과를 반환한다.
AssignmentElementList : AssignmentElementList , AssignmentElisionElement
  1. IteratorDestructuringAssignmentEvaluation of AssignmentElementListiteratorRecord 인수를 넘겨 수행한다.
  2. IteratorDestructuringAssignmentEvaluation of AssignmentElisionElementiteratorRecord 인수를 넘겨 수행한 결과를 반환한다.
AssignmentElisionElement : AssignmentElement
  1. IteratorDestructuringAssignmentEvaluation of AssignmentElementiteratorRecord 인수를 넘겨 수행한 결과를 반환한다.
AssignmentElisionElement : Elision AssignmentElement
  1. IteratorDestructuringAssignmentEvaluation of ElisioniteratorRecord 인수를 넘겨 수행한다.
  2. IteratorDestructuringAssignmentEvaluation of AssignmentElementiteratorRecord 인수를 넘겨 수행한 결과를 반환한다.
Elision : ,
  1. iteratorRecord.[[Done]]false이면,
    1. IteratorStep(iteratorRecord)를 수행한다.
  2. unused를 반환한다.
Elision : Elision ,
  1. IteratorDestructuringAssignmentEvaluation of ElisioniteratorRecord 인수를 넘겨 수행한다.
  2. iteratorRecord.[[Done]]false이면,
    1. IteratorStep(iteratorRecord)를 수행한다.
  3. unused를 반환한다.
AssignmentElement : DestructuringAssignmentTarget Initializeropt
  1. DestructuringAssignmentTargetObjectLiteral도 아니고 ArrayLiteral도 아니면,
    1. lRef를 ? Evaluation of DestructuringAssignmentTarget의 결과로 한다.
  2. valueundefined로 한다.
  3. iteratorRecord.[[Done]]false이면,
    1. next를 ? IteratorStepValue(iteratorRecord)로 한다.
    2. nextdone이 아니면,
      1. valuenext로 설정한다.
  4. Initializer가 존재하고 valueundefined이면,
    1. IsAnonymousFunctionDefinition(Initializer)이 true이고 IsIdentifierRef of DestructuringAssignmentTargettrue이면,
      1. targetStringValue of DestructuringAssignmentTarget로 한다.
      2. v를 ? NamedEvaluation of Initializertarget 인수를 넘겨 수행한 결과로 설정한다.
    2. 그 외에는,
      1. defaultValue를 ? Evaluation of Initializer 결과로 한다.
      2. v를 ? GetValue(defaultValue)로 설정한다.
  5. 그 외에는,
    1. vvalue로 한다.
  6. DestructuringAssignmentTargetObjectLiteral 또는 ArrayLiteral인 경우,
    1. nestedAssignmentPatternAssignmentPattern으로 한다. 이는 커버(cover)되어야 하며 DestructuringAssignmentTarget에 의해 포함된다.
    2. DestructuringAssignmentEvaluation of nestedAssignmentPatternv 인수를 넘겨 수행한 결과를 반환한다.
  7. PutValue(lRef, v)를 반환한다.
참고

왼쪽에서 오른쪽으로의 평가 순서는 구조 분해 패턴이 아닌 DestructuringAssignmentTarget을 이터레이터에 접근하거나 Initializer를 평가하기 전에 평가함으로써 유지된다.

AssignmentRestElement : ... DestructuringAssignmentTarget
  1. DestructuringAssignmentTargetObjectLiteral도 아니고 ArrayLiteral도 아니면,
    1. lRef를 ? Evaluation of DestructuringAssignmentTarget의 결과로 한다.
  2. A를 ! ArrayCreate(0)으로 한다.
  3. n을 0으로 한다.
  4. iteratorRecord.[[Done]]false인 동안 반복한다,
    1. next를 ? IteratorStepValue(iteratorRecord)로 한다.
    2. nextdone이 아니면,
      1. CreateDataPropertyOrThrow(A, ! ToString(𝔽(n)), next)를 수행한다.
      2. nn + 1로 설정한다.
  5. DestructuringAssignmentTargetObjectLiteral도 아니고 ArrayLiteral도 아니면,
    1. PutValue(lRef, A)를 반환한다.
  6. nestedAssignmentPatternAssignmentPattern으로 하고, 이는 커버(cover)되어야 하며 DestructuringAssignmentTarget에 의해 포함된다.
  7. DestructuringAssignmentEvaluation of nestedAssignmentPatternA 인수를 넘겨 수행한 결과를 반환한다.

13.15.5.6 런타임 의미론: KeyedDestructuringAssignmentEvaluation

구문 지시 연산 KeyedDestructuringAssignmentEvaluation은 value (ECMAScript 언어 값)과 propertyName (프로퍼티 키)를 인수로 받고, 정상 완료(normal completion) unused 또는 비정상 완료(abrupt completion)를 반환한다. 아래 생성식에 대해 조각별로 정의된다:

AssignmentElement : DestructuringAssignmentTarget Initializeropt
  1. DestructuringAssignmentTargetObjectLiteral도 아니고 ArrayLiteral도 아니면,
    1. lRef를 ? Evaluation of DestructuringAssignmentTarget의 결과로 한다.
  2. v를 ? GetV(value, propertyName)로 한다.
  3. Initializer가 존재하고 vundefined이면,
    1. IsAnonymousFunctionDefinition(Initializer)이 true이고 IsIdentifierRef of DestructuringAssignmentTargettrue이면,
      1. targetStringValue of DestructuringAssignmentTarget로 한다.
      2. rhsValue를 ? NamedEvaluation of Initializertarget 인수를 넘겨 수행한 결과로 한다.
    2. 그 외에는,
      1. defaultValue를 ? Evaluation of Initializer 결과로 한다.
      2. rhsValue를 ? GetValue(defaultValue)로 한다.
  4. 그 외에는,
    1. rhsValuev로 한다.
  5. DestructuringAssignmentTargetObjectLiteral 또는 ArrayLiteral인 경우,
    1. assignmentPatternAssignmentPattern으로 한다. 이는 커버(cover)되어야 하며 DestructuringAssignmentTarget에 의해 포함된다.
    2. DestructuringAssignmentEvaluation of assignmentPatternrhsValue 인수를 넘겨 수행한 결과를 반환한다.
  6. PutValue(lRef, rhsValue)를 반환한다.

13.16 콤마 연산자 ( , )

구문

Expression[In, Yield, Await] : AssignmentExpression[?In, ?Yield, ?Await] Expression[?In, ?Yield, ?Await] , AssignmentExpression[?In, ?Yield, ?Await]

13.16.1 런타임 의미론: 평가

Expression : Expression , AssignmentExpression
  1. lRef를 ? Evaluation of Expression의 결과로 한다.
  2. GetValue(lRef)를 수행한다.
  3. rRef를 ? Evaluation of AssignmentExpression의 결과로 한다.
  4. GetValue(rRef)를 반환한다.
참고

GetValue 는 값이 사용되지 않더라도 관측 가능한 부수 효과가 있을 수 있으므로 반드시 호출되어야 한다.

14 ECMAScript 언어: 문과 선언

구문

Statement[Yield, Await, Return] : BlockStatement[?Yield, ?Await, ?Return] VariableStatement[?Yield, ?Await] EmptyStatement ExpressionStatement[?Yield, ?Await] IfStatement[?Yield, ?Await, ?Return] BreakableStatement[?Yield, ?Await, ?Return] ContinueStatement[?Yield, ?Await] BreakStatement[?Yield, ?Await] [+Return] ReturnStatement[?Yield, ?Await] WithStatement[?Yield, ?Await, ?Return] LabelledStatement[?Yield, ?Await, ?Return] ThrowStatement[?Yield, ?Await] TryStatement[?Yield, ?Await, ?Return] DebuggerStatement Declaration[Yield, Await] : HoistableDeclaration[?Yield, ?Await, ~Default] ClassDeclaration[?Yield, ?Await, ~Default] LexicalDeclaration[+In, ?Yield, ?Await] HoistableDeclaration[Yield, Await, Default] : FunctionDeclaration[?Yield, ?Await, ?Default] GeneratorDeclaration[?Yield, ?Await, ?Default] AsyncFunctionDeclaration[?Yield, ?Await, ?Default] AsyncGeneratorDeclaration[?Yield, ?Await, ?Default] BreakableStatement[Yield, Await, Return] : IterationStatement[?Yield, ?Await, ?Return] SwitchStatement[?Yield, ?Await, ?Return]

14.1 문 의미론

14.1.1 런타임 의미론: 평가

HoistableDeclaration : GeneratorDeclaration AsyncFunctionDeclaration AsyncGeneratorDeclaration
  1. empty를 반환한다.
HoistableDeclaration : FunctionDeclaration
  1. Evaluation of FunctionDeclaration의 결과를 반환한다.
BreakableStatement : IterationStatement SwitchStatement
  1. newLabelSet을 비어 있는 새 List로 한다.
  2. LabelledEvaluation of this BreakableStatementnewLabelSet 인수를 넘겨 수행한 결과를 반환한다.

14.2 블록

구문

BlockStatement[Yield, Await, Return] : Block[?Yield, ?Await, ?Return] Block[Yield, Await, Return] : { StatementList[?Yield, ?Await, ?Return]opt } StatementList[Yield, Await, Return] : StatementListItem[?Yield, ?Await, ?Return] StatementList[?Yield, ?Await, ?Return] StatementListItem[?Yield, ?Await, ?Return] StatementListItem[Yield, Await, Return] : Statement[?Yield, ?Await, ?Return] Declaration[?Yield, ?Await]

14.2.1 정적 의미론: 초기 에러

Block : { StatementList }

14.2.2 런타임 의미론: 평가

Block : { }
  1. empty를 반환한다.
Block : { StatementList }
  1. oldEnv실행 중인 실행 컨텍스트(running execution context)의 LexicalEnvironment로 한다.
  2. blockEnvNewDeclarativeEnvironment(oldEnv)로 한다.
  3. BlockDeclarationInstantiation(StatementList, blockEnv)를 수행한다.
  4. 실행 중인 실행 컨텍스트의 LexicalEnvironment를 blockEnv로 설정한다.
  5. blockValueCompletion(Evaluation of StatementList)의 결과로 한다.
  6. 실행 중인 실행 컨텍스트의 LexicalEnvironment를 oldEnv로 설정한다.
  7. blockValue를 반환한다.
참고 1

어떤 방식으로 Block에서 벗어나더라도 LexicalEnvironment는 항상 이전 상태로 복원된다.

StatementList : StatementList StatementListItem
  1. sl을 ? Evaluation of StatementList의 결과로 한다.
  2. sCompletion(Evaluation of StatementListItem)의 결과로 한다.
  3. UpdateEmpty(s, sl)를 반환한다.
참고 2

StatementList의 값은 StatementList 내 마지막 값 생성 항목의 값이다. 예를 들어, 다음 eval 함수 호출은 모두 1을 반환한다:

eval("1;;;;;")
eval("1;{}")
eval("1;var a;")

14.2.3 BlockDeclarationInstantiation ( code, env )

추상 연산 BlockDeclarationInstantiation은 code (파스 노드(Parse Node))와 env (선언적 환경 레코드(Declarative Environment Record))를 인수로 받고 unused를 반환한다. code는 블록의 본문에 해당하는 파스 노드(Parse Node)이다. env는 바인딩이 생성될 환경 레코드(Environment Record)이다.

참고

Block 또는 CaseBlock이 평가될 때, 새로운 선언적 환경 레코드가 생성되고, 블록 내 선언된 각 블록 범위 변수, 상수, 함수, 클래스에 대한 바인딩이 환경 레코드에 인스턴스화된다.

호출 시 다음 단계를 수행한다:

  1. declarationsLexicallyScopedDeclarations of code로 한다.
  2. privateEnv실행 중인 실행 컨텍스트(running execution context)의 PrivateEnvironment로 한다.
  3. declarations의 각 요소 d에 대해, 다음을 수행한다:
    1. BoundNames of d의 각 요소 dn에 대해, 다음을 수행한다:
      1. IsConstantDeclaration of dtrue이면,
        1. env.CreateImmutableBinding(dn, true)을 수행한다.
      2. 그 외에는,
        1. env.CreateMutableBinding(dn, false)을 수행한다. 참고: 이 단계는 B.3.2.6 절에서 대체된다.
    2. dFunctionDeclaration, GeneratorDeclaration, AsyncFunctionDeclaration, AsyncGeneratorDeclaration 중 하나라면, 다음을 수행한다:
      1. fnBoundNames of d의 유일한 요소로 한다.
      2. foInstantiateFunctionObject of denvprivateEnv 인수를 넘겨 수행한 결과로 한다.
      3. env.InitializeBinding(fn, fo)를 수행한다. 참고: 이 단계는 B.3.2.6 절에서 대체된다.
  4. unused를 반환한다.

14.3 선언과 변수 문

14.3.1 let 및 const 선언

참고

letconst 선언은 실행 중인 실행 컨텍스트(running execution context)의 LexicalEnvironment에 스코프를 갖는 변수를 정의한다. 이 변수들은 해당 환경 레코드(Environment Record)가 인스턴스화될 때 생성되지만, 변수의 LexicalBinding이 평가되기 전까지는 어떠한 방식으로든 접근할 수 없다. LexicalBindingInitializer를 포함하는 경우, 해당 변수는 InitializerAssignmentExpressionLexicalBinding이 평가될 때 값을 할당받으며, 변수 생성 시 할당받지 않는다. let 선언 내의 LexicalBindingInitializer가 없는 경우, 해당 변수는 LexicalBinding이 평가될 때 undefined가 할당된다.

구문

LexicalDeclaration[In, Yield, Await] : LetOrConst BindingList[?In, ?Yield, ?Await] ; LetOrConst : let const BindingList[In, Yield, Await] : LexicalBinding[?In, ?Yield, ?Await] BindingList[?In, ?Yield, ?Await] , LexicalBinding[?In, ?Yield, ?Await] LexicalBinding[In, Yield, Await] : BindingIdentifier[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]opt BindingPattern[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]

14.3.1.1 정적 의미론: 초기 에러

LexicalDeclaration : LetOrConst BindingList ; LexicalBinding : BindingIdentifier Initializeropt

14.3.1.2 런타임 의미론: 평가

LexicalDeclaration : LetOrConst BindingList ;
  1. Evaluation of BindingList를 수행한다.
  2. empty를 반환한다.
BindingList : BindingList , LexicalBinding
  1. Evaluation of BindingList를 수행한다.
  2. Evaluation of LexicalBinding을 반환한다.
LexicalBinding : BindingIdentifier
  1. lhs를 ! ResolveBinding(StringValue of BindingIdentifier)로 한다.
  2. InitializeReferencedBinding(lhs, undefined)를 수행한다.
  3. empty를 반환한다.
참고

정적 의미론 규칙에 의해 이 형태의 LexicalBindingconst 선언에 등장하는 일은 없다.

LexicalBinding : BindingIdentifier Initializer
  1. bindingIdStringValue of BindingIdentifier로 한다.
  2. lhs를 ! ResolveBinding(bindingId)로 한다.
  3. IsAnonymousFunctionDefinition(Initializer)이 true이면,
    1. value를 ? NamedEvaluation of InitializerbindingId 인수를 넘겨 수행한 결과로 한다.
  4. 그 외에는,
    1. rhs를 ? Evaluation of Initializer의 결과로 한다.
    2. value를 ? GetValue(rhs)로 한다.
  5. InitializeReferencedBinding(lhs, value)를 수행한다.
  6. empty를 반환한다.
LexicalBinding : BindingPattern Initializer
  1. rhs를 ? Evaluation of Initializer의 결과로 한다.
  2. value를 ? GetValue(rhs)로 한다.
  3. env실행 중인 실행 컨텍스트(running execution context)의 LexicalEnvironment로 한다.
  4. BindingInitialization of BindingPatternvalueenv를 인수로 넘겨 수행한 결과를 반환한다.

14.3.2 변수 문

참고

var 문은 실행 중인 실행 컨텍스트(running execution context)의 VariableEnvironment에 스코프를 갖는 변수를 선언한다. var 변수는 해당 환경 레코드(Environment Record)가 인스턴스화될 때 생성되고, 생성 시 undefined로 초기화된다. 어떤 VariableEnvironment의 스코프 내에서는 동일한 BindingIdentifier가 둘 이상의 VariableDeclaration에 나타날 수 있으나, 이 선언들은 모여 하나의 변수만 정의한다. VariableDeclarationInitializer를 포함하는 경우, 해당 변수는 InitializerAssignmentExpressionVariableDeclaration이 실행될 때 값을 할당받으며, 변수 생성 시 할당받지 않는다.

구문

VariableStatement[Yield, Await] : var VariableDeclarationList[+In, ?Yield, ?Await] ; VariableDeclarationList[In, Yield, Await] : VariableDeclaration[?In, ?Yield, ?Await] VariableDeclarationList[?In, ?Yield, ?Await] , VariableDeclaration[?In, ?Yield, ?Await] VariableDeclaration[In, Yield, Await] : BindingIdentifier[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]opt BindingPattern[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]

14.3.2.1 런타임 의미론: 평가

VariableStatement : var VariableDeclarationList ;
  1. Evaluation of VariableDeclarationList를 수행한다.
  2. empty를 반환한다.
VariableDeclarationList : VariableDeclarationList , VariableDeclaration
  1. Evaluation of VariableDeclarationList를 수행한다.
  2. Evaluation of VariableDeclaration을 반환한다.
VariableDeclaration : BindingIdentifier
  1. empty를 반환한다.
VariableDeclaration : BindingIdentifier Initializer
  1. bindingIdStringValue of BindingIdentifier로 한다.
  2. lhs를 ? ResolveBinding(bindingId)로 한다.
  3. IsAnonymousFunctionDefinition(Initializer)가 true이면,
    1. value를 ? NamedEvaluation of InitializerbindingId 인수를 넘겨 수행한 결과로 한다.
  4. 그 외에는,
    1. rhs를 ? Evaluation of Initializer의 결과로 한다.
    2. value를 ? GetValue(rhs)로 한다.
  5. PutValue(lhs, value)를 수행한다.
  6. empty를 반환한다.
참고

VariableDeclaration이 with 문 내부에 중첩되어 있고 해당 BindingIdentifier가 with 문의 바인딩 객체의 프로퍼티 이름(property name)과 같으면, 5 단계는 VariableEnvironment 바인딩 대신 프로퍼티에 value를 할당한다.

VariableDeclaration : BindingPattern Initializer
  1. rhs를 ? Evaluation of Initializer의 결과로 한다.
  2. rVal을 ? GetValue(rhs)로 한다.
  3. BindingInitialization of BindingPatternrValundefined를 인수로 넘겨 수행한 결과를 반환한다.

14.3.3 구조 분해 바인딩 패턴

구문

BindingPattern[Yield, Await] : ObjectBindingPattern[?Yield, ?Await] ArrayBindingPattern[?Yield, ?Await] ObjectBindingPattern[Yield, Await] : { } { BindingRestProperty[?Yield, ?Await] } { BindingPropertyList[?Yield, ?Await] } { BindingPropertyList[?Yield, ?Await] , BindingRestProperty[?Yield, ?Await]opt } ArrayBindingPattern[Yield, Await] : [ Elisionopt BindingRestElement[?Yield, ?Await]opt ] [ BindingElementList[?Yield, ?Await] ] [ BindingElementList[?Yield, ?Await] , Elisionopt BindingRestElement[?Yield, ?Await]opt ] BindingRestProperty[Yield, Await] : ... BindingIdentifier[?Yield, ?Await] BindingPropertyList[Yield, Await] : BindingProperty[?Yield, ?Await] BindingPropertyList[?Yield, ?Await] , BindingProperty[?Yield, ?Await] BindingElementList[Yield, Await] : BindingElisionElement[?Yield, ?Await] BindingElementList[?Yield, ?Await] , BindingElisionElement[?Yield, ?Await] BindingElisionElement[Yield, Await] : Elisionopt BindingElement[?Yield, ?Await] BindingProperty[Yield, Await] : SingleNameBinding[?Yield, ?Await] PropertyName[?Yield, ?Await] : BindingElement[?Yield, ?Await] BindingElement[Yield, Await] : SingleNameBinding[?Yield, ?Await] BindingPattern[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt SingleNameBinding[Yield, Await] : BindingIdentifier[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt BindingRestElement[Yield, Await] : ... BindingIdentifier[?Yield, ?Await] ... BindingPattern[?Yield, ?Await]

14.3.3.1 런타임 의미론: PropertyBindingInitialization

구문 지시 연산 PropertyBindingInitialization은 value (ECMAScript 언어 값)과 environment (환경 레코드(Environment Record) 또는 undefined)를 인수로 받고, 정상 완료(normal completion)List (모든 바인딩된 프로퍼티 키의 리스트) 또는 비정상 완료(abrupt completion)를 반환한다. 모든 바인딩된 프로퍼티 이름의 리스트를 수집한다. 다음 생성식에 대해 조각별로 정의된다:

BindingPropertyList : BindingPropertyList , BindingProperty
  1. boundNames를 ? PropertyBindingInitialization of BindingPropertyListvalueenvironment를 인수로 넘겨 수행한 결과로 한다.
  2. nextNames를 ? PropertyBindingInitialization of BindingPropertyvalueenvironment를 인수로 넘겨 수행한 결과로 한다.
  3. boundNamesnextNames리스트 연결(list-concatenation) 결과를 반환한다.
BindingProperty : SingleNameBinding
  1. nameBoundNames of SingleNameBinding의 유일한 요소로 한다.
  2. KeyedBindingInitialization of SingleNameBindingvalue, environment, name을 인수로 넘겨 수행한다.
  3. « name »를 반환한다.
BindingProperty : PropertyName : BindingElement
  1. P를 ? Evaluation of PropertyName의 결과로 한다.
  2. KeyedBindingInitialization of BindingElementvalue, environment, P를 인수로 넘겨 수행한다.
  3. « P »를 반환한다.

14.3.3.2 런타임 의미론: RestBindingInitialization

구문 지시 연산 RestBindingInitialization은 value (ECMAScript 언어 값), environment (환경 레코드(Environment Record) 또는 undefined), excludedNames (List 타입의 프로퍼티 키 리스트)를 인수로 받고, 정상 완료(normal completion) unused 또는 비정상 완료(abrupt completion)를 반환한다. 다음 생성식에 대해 조각별로 정의된다:

BindingRestProperty : ... BindingIdentifier
  1. lhs를 ? ResolveBinding(StringValue of BindingIdentifier, environment)로 한다.
  2. restObjOrdinaryObjectCreate(%Object.prototype%)로 한다.
  3. CopyDataProperties(restObj, value, excludedNames)를 수행한다.
  4. environmentundefined이면, ? PutValue(lhs, restObj)를 반환한다.
  5. InitializeReferencedBinding(lhs, restObj)를 반환한다.

14.3.3.3 런타임 의미론: KeyedBindingInitialization

구문 지시 연산 KeyedBindingInitialization은 value (ECMAScript 언어 값), environment (환경 레코드(Environment Record) 또는 undefined), propertyName (프로퍼티 키)를 인수로 받고, 정상 완료(normal completion) unused 또는 비정상 완료(abrupt completion)를 반환한다.

참고

environmentundefined가 전달되는 경우, 초기화 값을 할당하기 위해 PutValue 연산을 사용해야 함을 나타낸다. 이는 비엄격 함수(non-strict functions)의 형식적 매개변수 리스트의 경우이다. 이런 경우, 동일한 이름의 여러 매개변수가 있을 수 있으므로 형식적 매개변수 바인딩이 미리 초기화된다.

다음 생성식에 대해 조각별로 정의된다:

BindingElement : BindingPattern Initializeropt
  1. v를 ? GetV(value, propertyName)로 한다.
  2. Initializer가 존재하고 vundefined이면,
    1. defaultValue를 ? Evaluation of Initializer의 결과로 한다.
    2. v를 ? GetValue(defaultValue)로 설정한다.
  3. BindingInitialization of BindingPatternvenvironment를 인수로 넘겨 수행한 결과를 반환한다.
SingleNameBinding : BindingIdentifier Initializeropt
  1. bindingIdStringValue of BindingIdentifier로 한다.
  2. lhs를 ? ResolveBinding(bindingId, environment)로 한다.
  3. v를 ? GetV(value, propertyName)로 한다.
  4. Initializer가 존재하고 vundefined이면,
    1. IsAnonymousFunctionDefinition(Initializer)가 true이면,
      1. v를 ? NamedEvaluation of InitializerbindingId 인수를 넘겨 수행한 결과로 설정한다.
    2. 그 외에는,
      1. defaultValue를 ? Evaluation of Initializer의 결과로 한다.
      2. v를 ? GetValue(defaultValue)로 설정한다.
  5. environmentundefined이면, ? PutValue(lhs, v)를 반환한다.
  6. InitializeReferencedBinding(lhs, v)를 반환한다.

14.4 빈 문

구문

EmptyStatement : ;

14.4.1 런타임 의미론: 평가

EmptyStatement : ;
  1. empty를 반환한다.

14.5 표현식 문

구문

ExpressionStatement[Yield, Await] : [lookahead ∉ { {, function, async [no LineTerminator here] function, class, let [ }] Expression[+In, ?Yield, ?Await] ; 참고

ExpressionStatement는 U+007B(LEFT CURLY BRACKET)로 시작할 수 없다. 왜냐하면 이는 Block과 혼동될 수 있기 때문이다. ExpressionStatementfunction 또는 class 키워드로 시작할 수 없는데, 이는 FunctionDeclaration, GeneratorDeclaration, 또는 ClassDeclaration과 혼동될 수 있기 때문이다. ExpressionStatementasync function으로 시작할 수 없는데, 이는 AsyncFunctionDeclaration 또는 AsyncGeneratorDeclaration과 혼동될 수 있기 때문이다. ExpressionStatementlet [의 두 토큰 시퀀스로 시작할 수 없는데, 이는 LexicalDeclaration의 첫 LexicalBindingArrayBindingPatternlet 선언과 혼동될 수 있기 때문이다.

14.5.1 런타임 의미론: 평가

ExpressionStatement : Expression ;
  1. exprRef를 ? Evaluation of Expression의 결과로 한다.
  2. GetValue(exprRef)를 반환한다.

14.6 if

구문

IfStatement[Yield, Await, Return] : if ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] else Statement[?Yield, ?Await, ?Return] if ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] [lookahead ≠ else] 참고
lookahead 제한 [lookahead ≠ else]는 고전적인 "dangling else" 문제를 일반적인 방식으로 해결한다. 즉, 연관된 if의 선택이 모호할 경우, else는 후보 if들 중 가장 가까운(가장 안쪽의) 것과 연관된다.

14.6.1 정적 의미론: 초기 에러

IfStatement : if ( Expression ) Statement else Statement IfStatement : if ( Expression ) Statement 참고

이 규칙은 B.3.1에 명시된 확장이 구현된 경우에만 적용해야 한다.

14.6.2 런타임 의미론: 평가

IfStatement : if ( Expression ) Statement else Statement
  1. exprRef를 ? Evaluation of Expression의 결과로 한다.
  2. exprValueToBoolean(? GetValue(exprRef))의 결과로 한다.
  3. exprValuetrue이면,
    1. stmtCompletionCompletion(Evaluation of 첫 번째 Statement)의 결과로 한다.
  4. 그 외에는,
    1. stmtCompletionCompletion(Evaluation of 두 번째 Statement)의 결과로 한다.
  5. UpdateEmpty(stmtCompletion, undefined)를 반환한다.
IfStatement : if ( Expression ) Statement
  1. exprRef를 ? Evaluation of Expression의 결과로 한다.
  2. exprValueToBoolean(? GetValue(exprRef))의 결과로 한다.
  3. exprValuefalse이면,
    1. undefined를 반환한다.
  4. 그 외에는,
    1. stmtCompletionCompletion(Evaluation of Statement)의 결과로 한다.
    2. UpdateEmpty(stmtCompletion, undefined)를 반환한다.

14.7 반복문

구문

IterationStatement[Yield, Await, Return] : DoWhileStatement[?Yield, ?Await, ?Return] WhileStatement[?Yield, ?Await, ?Return] ForStatement[?Yield, ?Await, ?Return] ForInOfStatement[?Yield, ?Await, ?Return]

14.7.1 의미론

14.7.1.1 LoopContinues ( completion, labelSet )

추상 연산 LoopContinues는 completion (Completion Record) 와 labelSet (문자열 리스트(List of Strings))를 인수로 받아 Boolean을 반환한다. 호출 시 다음 단계를 수행한다:

  1. completionnormal completion이면 true를 반환한다.
  2. completioncontinue completion이 아니면 false를 반환한다.
  3. completion.[[Target]]empty이면 true를 반환한다.
  4. labelSetcompletion.[[Target]]을 포함하면 true를 반환한다.
  5. false를 반환한다.
참고

Statement 부분의 IterationStatement 내부에서는 ContinueStatement 를 사용하여 새로운 반복을 시작할 수 있다.

14.7.1.2 런타임 의미론: LoopEvaluation

구문 지시 연산 LoopEvaluation은 labelSet (문자열 리스트(List of Strings))를 인수로 받고, 정상 완료(normal completion)ECMAScript 언어 값 또는 비정상 완료(abrupt completion)를 반환한다. 다음 생성식에 대해 조각별로 정의된다:

IterationStatement : DoWhileStatement
  1. DoWhileLoopEvaluation of DoWhileStatementlabelSet 인수를 넘겨 수행한 결과를 반환한다.
IterationStatement : WhileStatement
  1. WhileLoopEvaluation of WhileStatementlabelSet 인수를 넘겨 수행한 결과를 반환한다.
IterationStatement : ForStatement
  1. ForLoopEvaluation of ForStatementlabelSet 인수를 넘겨 수행한 결과를 반환한다.
IterationStatement : ForInOfStatement
  1. ForInOfLoopEvaluation of ForInOfStatementlabelSet 인수를 넘겨 수행한 결과를 반환한다.

14.7.2 do-while

구문

DoWhileStatement[Yield, Await, Return] : do Statement[?Yield, ?Await, ?Return] while ( Expression[+In, ?Yield, ?Await] ) ;

14.7.2.1 정적 의미론: 초기 에러

DoWhileStatement : do Statement while ( Expression ) ; 참고

이 규칙은 B.3.1에 명시된 확장이 구현된 경우에만 적용된다.

14.7.2.2 런타임 의미론: DoWhileLoopEvaluation

구문 지시 연산 DoWhileLoopEvaluation은 labelSet (문자열 리스트(List of Strings))를 인수로 받고, 정상 완료(normal completion)ECMAScript 언어 값 또는 비정상 완료(abrupt completion)를 반환한다. 다음 생성식에 대해 조각별로 정의된다:

DoWhileStatement : do Statement while ( Expression ) ;
  1. Vundefined로 한다.
  2. 반복한다,
    1. stmtResultCompletion(Evaluation of Statement)의 결과로 한다.
    2. LoopContinues(stmtResult, labelSet)가 false이면, ? UpdateEmpty(stmtResult, V)를 반환한다.
    3. stmtResult.[[Value]]empty가 아니면, VstmtResult.[[Value]]를 설정한다.
    4. exprRef를 ? Evaluation of Expression의 결과로 한다.
    5. exprValue를 ? GetValue(exprRef)의 결과로 한다.
    6. ToBoolean(exprValue) 가 false이면 V를 반환한다.

14.7.3 while

구문

WhileStatement[Yield, Await, Return] : while ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return]

14.7.3.1 정적 의미론: 초기 에러

WhileStatement : while ( Expression ) Statement 참고

이 규칙은 B.3.1에 명시된 확장이 구현된 경우에만 적용한다.

14.7.3.2 런타임 의미론: WhileLoopEvaluation

구문 지시 연산 WhileLoopEvaluation은 labelSet (문자열 리스트(List of Strings))를 인수로 받고, 정상 완료(normal completion)ECMAScript 언어 값 또는 비정상 완료(abrupt completion)를 반환한다. 다음 생성식에 대해 조각별로 정의된다:

WhileStatement : while ( Expression ) Statement
  1. Vundefined로 한다.
  2. 반복한다,
    1. exprRef를 ? Evaluation of Expression의 결과로 한다.
    2. exprValue를 ? GetValue(exprRef)의 결과로 한다.
    3. ToBoolean(exprValue) 가 false이면 V를 반환한다.
    4. stmtResultCompletion(Evaluation of Statement)의 결과로 한다.
    5. LoopContinues(stmtResult, labelSet)가 false이면, ? UpdateEmpty(stmtResult, V)를 반환한다.
    6. stmtResult.[[Value]]empty가 아니면, VstmtResult.[[Value]]를 설정한다.

14.7.4 for

구문

ForStatement[Yield, Await, Return] : for ( [lookahead ≠ let [] Expression[~In, ?Yield, ?Await]opt ; Expression[+In, ?Yield, ?Await]opt ; Expression[+In, ?Yield, ?Await]opt ) Statement[?Yield, ?Await, ?Return] for ( var VariableDeclarationList[~In, ?Yield, ?Await] ; Expression[+In, ?Yield, ?Await]opt ; Expression[+In, ?Yield, ?Await]opt ) Statement[?Yield, ?Await, ?Return] for ( LexicalDeclaration[~In, ?Yield, ?Await] Expression[+In, ?Yield, ?Await]opt ; Expression[+In, ?Yield, ?Await]opt ) Statement[?Yield, ?Await, ?Return]

14.7.4.1 정적 의미론: 초기 에러

ForStatement : for ( Expressionopt ; Expressionopt ; Expressionopt ) Statement for ( var VariableDeclarationList ; Expressionopt ; Expressionopt ) Statement for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement 참고

이 규칙은 B.3.1에 명시된 확장이 구현된 경우에만 적용된다.

ForStatement : for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement

14.7.4.2 런타임 의미론: ForLoopEvaluation

구문 지시 연산 ForLoopEvaluation은 labelSet (문자열 리스트(List of Strings))를 인수로 받고, 정상 완료(normal completion)ECMAScript 언어 값 또는 비정상 완료(abrupt completion)를 반환한다. 다음 생성식에 대해 조각별로 정의된다:

ForStatement : for ( Expressionopt ; Expressionopt ; Expressionopt ) Statement
  1. 첫 번째 Expression이 존재하면,
    1. exprRef를 ? Evaluation of 첫 번째 Expression의 결과로 한다.
    2. GetValue(exprRef)를 수행한다.
  2. 두 번째 Expression이 존재하면 test를 두 번째 Expression로, 아니면 testempty로 한다.
  3. 세 번째 Expression이 존재하면 increment를 세 번째 Expression로, 아니면 incrementempty로 한다.
  4. ForBodyEvaluation(test, increment, Statement, « », labelSet)을 반환한다.
ForStatement : for ( var VariableDeclarationList ; Expressionopt ; Expressionopt ) Statement
  1. Evaluation of VariableDeclarationList를 수행한다.
  2. 첫 번째 Expression이 존재하면 test를 첫 번째 Expression로, 아니면 testempty로 한다.
  3. 두 번째 Expression이 존재하면 increment를 두 번째 Expression로, 아니면 incrementempty로 한다.
  4. ForBodyEvaluation(test, increment, Statement, « », labelSet)을 반환한다.
ForStatement : for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement
  1. oldEnv실행 중인 실행 컨텍스트(running execution context)의 LexicalEnvironment로 한다.
  2. loopEnvNewDeclarativeEnvironment(oldEnv)로 한다.
  3. isConstIsConstantDeclaration of LexicalDeclaration의 결과로 한다.
  4. boundNamesBoundNames of LexicalDeclaration의 결과로 한다.
  5. boundNames의 각 요소 dn에 대해, 다음을 수행한다:
    1. isConsttrue이면,
      1. loopEnv.CreateImmutableBinding(dn, true)을 수행한다.
    2. 그 외에는,
      1. loopEnv.CreateMutableBinding(dn, false)을 수행한다.
  6. 실행 중인 실행 컨텍스트의 LexicalEnvironment를 loopEnv로 설정한다.
  7. forDclCompletion(Evaluation of LexicalDeclaration)의 결과로 한다.
  8. forDcl비정상 완료(abrupt completion)이면,
    1. 실행 중인 실행 컨텍스트의 LexicalEnvironment를 oldEnv로 설정한다.
    2. forDcl을 반환한다.
  9. isConstfalse이면 perIterationLetsboundNames로, 아니면 perIterationLets를 비어 있는 List로 한다.
  10. 첫 번째 Expression이 존재하면 test를 첫 번째 Expression로, 아니면 testempty로 한다.
  11. 두 번째 Expression이 존재하면 increment를 두 번째 Expression로, 아니면 incrementempty로 한다.
  12. bodyResultCompletion(ForBodyEvaluation(test, increment, Statement, perIterationLets, labelSet))의 결과로 한다.
  13. 실행 중인 실행 컨텍스트의 LexicalEnvironment를 oldEnv로 설정한다.
  14. bodyResult를 반환한다.

14.7.4.3 ForBodyEvaluation ( test, increment, stmt, perIterationBindings, labelSet )

추상 연산 ForBodyEvaluation은 test (Expression 파스 노드(Parse Node) 또는 empty), increment (Expression 파스 노드(Parse Node) 또는 empty), stmt (Statement 파스 노드(Parse Node)), perIterationBindings (문자열 리스트(List of Strings)), labelSet (문자열 리스트(List of Strings))를 인수로 받고, 정상 완료(normal completion)ECMAScript 언어 값 또는 비정상 완료(abrupt completion)를 반환한다. 호출 시 다음 단계를 수행한다:

  1. Vundefined로 한다.
  2. CreatePerIterationEnvironment(perIterationBindings)를 수행한다.
  3. 반복한다,
    1. testempty가 아니면,
      1. testRef를 ? Evaluation of test의 결과로 한다.
      2. testValue를 ? GetValue(testRef)의 결과로 한다.
      3. ToBoolean(testValue) 가 false이면 V를 반환한다.
    2. resultCompletion(Evaluation of stmt)의 결과로 한다.
    3. LoopContinues(result, labelSet)가 false이면, ? UpdateEmpty(result, V)를 반환한다.
    4. result.[[Value]]empty가 아니면, Vresult.[[Value]]를 설정한다.
    5. CreatePerIterationEnvironment(perIterationBindings)를 수행한다.
    6. incrementempty가 아니면,
      1. incRef를 ? Evaluation of increment의 결과로 한다.
      2. GetValue(incRef)를 수행한다.

14.7.4.4 CreatePerIterationEnvironment ( perIterationBindings )

추상 연산 CreatePerIterationEnvironment는 perIterationBindings (문자열 리스트(List of Strings))를 인수로 받고, 정상 완료(normal completion) unused 또는 throw completion를 반환한다. 호출 시 다음 단계를 수행한다:

  1. perIterationBindings에 요소가 하나라도 있으면,
    1. lastIterationEnv실행 중인 실행 컨텍스트(running execution context)의 LexicalEnvironment로 한다.
    2. outerlastIterationEnv.[[OuterEnv]]로 한다.
    3. Assert: outernull이 아니다.
    4. thisIterationEnvNewDeclarativeEnvironment(outer)로 한다.
    5. perIterationBindings의 각 요소 bn에 대해, 다음을 수행한다:
      1. thisIterationEnv.CreateMutableBinding(bn, false)를 수행한다.
      2. lastValue를 ? lastIterationEnv.GetBindingValue(bn, true)로 한다.
      3. thisIterationEnv.InitializeBinding(bn, lastValue)를 수행한다.
    6. 실행 중인 실행 컨텍스트의 LexicalEnvironment를 thisIterationEnv로 설정한다.
  2. unused를 반환한다.

14.7.5 for-in, for-of, 그리고 for-await-of

구문

ForInOfStatement[Yield, Await, Return] : for ( [lookahead ≠ let [] LeftHandSideExpression[?Yield, ?Await] in Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( var ForBinding[?Yield, ?Await] in Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( ForDeclaration[?Yield, ?Await] in Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( [lookahead ∉ { let, async of }] LeftHandSideExpression[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( var ForBinding[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( ForDeclaration[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] [+Await] for await ( [lookahead ≠ let] LeftHandSideExpression[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] [+Await] for await ( var ForBinding[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] [+Await] for await ( ForDeclaration[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] ForDeclaration[Yield, Await] : LetOrConst ForBinding[?Yield, ?Await] ForBinding[Yield, Await] : BindingIdentifier[?Yield, ?Await] BindingPattern[?Yield, ?Await] 참고

이 절은 부록 B.3.5에 의해 확장된다.

14.7.5.1 정적 의미론: 초기 에러

ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement for ( var ForBinding in Expression ) Statement for ( ForDeclaration in Expression ) Statement for ( LeftHandSideExpression of AssignmentExpression ) Statement for ( var ForBinding of AssignmentExpression ) Statement for ( ForDeclaration of AssignmentExpression ) Statement for await ( LeftHandSideExpression of AssignmentExpression ) Statement for await ( var ForBinding of AssignmentExpression ) Statement for await ( ForDeclaration of AssignmentExpression ) Statement 참고

이 규칙은 B.3.1에 명시된 확장이 구현된 경우에만 적용된다.

ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement for ( LeftHandSideExpression of AssignmentExpression ) Statement for await ( LeftHandSideExpression of AssignmentExpression ) Statement ForInOfStatement : for ( ForDeclaration in Expression ) Statement for ( ForDeclaration of AssignmentExpression ) Statement for await ( ForDeclaration of AssignmentExpression ) Statement

14.7.5.2 정적 의미론: IsDestructuring

구문 지시 연산 IsDestructuring은 인수를 받지 않으며 Boolean을 반환한다. 다음 생성식에 대해 조각별로 정의된다:

MemberExpression : PrimaryExpression
  1. PrimaryExpressionObjectLiteral 또는 ArrayLiteral인 경우, true를 반환한다.
  2. false를 반환한다.
MemberExpression : MemberExpression [ Expression ] MemberExpression . IdentifierName MemberExpression TemplateLiteral SuperProperty MetaProperty new MemberExpression Arguments MemberExpression . PrivateIdentifier NewExpression : new NewExpression LeftHandSideExpression : CallExpression OptionalExpression
  1. false를 반환한다.
ForDeclaration : LetOrConst ForBinding
  1. IsDestructuring of ForBinding의 결과를 반환한다.
ForBinding : BindingIdentifier
  1. false를 반환한다.
ForBinding : BindingPattern
  1. true를 반환한다.
참고

이 절은 부록 B.3.5에 의해 확장된다.

14.7.5.3 런타임 의미론: ForDeclarationBindingInitialization

구문 지시 연산 ForDeclarationBindingInitialization은 value (ECMAScript 언어 값)과 environment (환경 레코드(Environment Record) 또는 undefined)를 인수로 받고, 정상 완료(normal completion) unused 또는 비정상 완료(abrupt completion)를 반환한다.

참고

environmentundefined가 전달되면, 초기화 값을 할당하기 위해 PutValue 연산을 사용해야 함을 나타낸다. 이는 var 문과 일부 비엄격 함수(non-strict functions)의 형식적 매개변수 리스트의 경우이다( 10.2.11 참조). 이러한 경우, 렉시컬 바인딩이 호이스팅되고 초기화자 평가 전에 미리 초기화된다.

다음 생성식에 대해 조각별로 정의된다:

ForDeclaration : LetOrConst ForBinding
  1. BindingInitialization of ForBindingvalueenvironment를 인수로 넘겨 수행한 결과를 반환한다.

14.7.5.4 런타임 의미론: ForDeclarationBindingInstantiation

구문 지시 연산 ForDeclarationBindingInstantiation은 environment (선언적 환경 레코드(Declarative Environment Record))를 인수로 받고 unused를 반환한다. 다음 생성식에 대해 조각별로 정의된다:

ForDeclaration : LetOrConst ForBinding
  1. ForBindingBoundNames의 각 요소 name에 대해, 다음을 수행한다:
    1. IsConstantDeclaration of LetOrConsttrue이면,
      1. environment.CreateImmutableBinding(name, true)를 수행한다.
    2. 그 외에는,
      1. environment.CreateMutableBinding(name, false)를 수행한다.
  2. unused를 반환한다.

14.7.5.5 런타임 의미론: ForInOfLoopEvaluation

구문 지시 연산 ForInOfLoopEvaluation은 labelSet (문자열 리스트(List of Strings))를 인수로 받고, 정상 완료(normal completion)ECMAScript 언어 값 또는 비정상 완료(abrupt completion)를 반환한다. 다음 생성식에 대해 조각별로 정의된다:

ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement
  1. keyResult를 ? ForIn/OfHeadEvaluation(« », Expression, enumerate)의 결과로 한다.
  2. ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement, keyResult, enumerate, assignment, labelSet)을 반환한다.
ForInOfStatement : for ( var ForBinding in Expression ) Statement
  1. keyResult를 ? ForIn/OfHeadEvaluation(« », Expression, enumerate)의 결과로 한다.
  2. ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult, enumerate, var-binding, labelSet)을 반환한다.
ForInOfStatement : for ( ForDeclaration in Expression ) Statement
  1. keyResult를 ? ForIn/OfHeadEvaluation(BoundNames of ForDeclaration, Expression, enumerate)의 결과로 한다.
  2. ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult, enumerate, lexical-binding, labelSet)을 반환한다.
ForInOfStatement : for ( LeftHandSideExpression of AssignmentExpression ) Statement
  1. keyResult를 ? ForIn/OfHeadEvaluation(« », AssignmentExpression, iterate)의 결과로 한다.
  2. ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement, keyResult, iterate, assignment, labelSet)을 반환한다.
ForInOfStatement : for ( var ForBinding of AssignmentExpression ) Statement
  1. keyResult를 ? ForIn/OfHeadEvaluation(« », AssignmentExpression, iterate)의 결과로 한다.
  2. ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult, iterate, var-binding, labelSet)을 반환한다.
ForInOfStatement : for ( ForDeclaration of AssignmentExpression ) Statement
  1. keyResult를 ? ForIn/OfHeadEvaluation(BoundNames of ForDeclaration, AssignmentExpression, iterate)의 결과로 한다.
  2. ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult, iterate, lexical-binding, labelSet)을 반환한다.
ForInOfStatement : for await ( LeftHandSideExpression of AssignmentExpression ) Statement
  1. keyResult를 ? ForIn/OfHeadEvaluation(« », AssignmentExpression, async-iterate)의 결과로 한다.
  2. ForIn/OfBodyEvaluation(LeftHandSideExpression, Statement, keyResult, iterate, assignment, labelSet, async)을 반환한다.
ForInOfStatement : for await ( var ForBinding of AssignmentExpression ) Statement
  1. keyResult를 ? ForIn/OfHeadEvaluation(« », AssignmentExpression, async-iterate)의 결과로 한다.
  2. ForIn/OfBodyEvaluation(ForBinding, Statement, keyResult, iterate, var-binding, labelSet, async)을 반환한다.
ForInOfStatement : for await ( ForDeclaration of AssignmentExpression ) Statement
  1. keyResult를 ? ForIn/OfHeadEvaluation(BoundNames of ForDeclaration, AssignmentExpression, async-iterate)의 결과로 한다.
  2. ForIn/OfBodyEvaluation(ForDeclaration, Statement, keyResult, iterate, lexical-binding, labelSet, async)을 반환한다.
참고

이 절은 부록 B.3.5에 의해 확장된다.

14.7.5.6 ForIn/OfHeadEvaluation ( uninitializedBoundNames, expr, iterationKind )

추상 연산 ForIn/OfHeadEvaluation은 uninitializedBoundNames (문자열의 리스트(List)), expr (Expression 파스 노드(Parse Node) 또는 AssignmentExpression 파스 노드(Parse Node)), iterationKind (enumerate, iterate, 또는 async-iterate)를 인수로 받고, 정상 완료(normal completion)이터레이터 레코드(Iterator Record) 또는 비정상 완료(abrupt completion)를 반환한다. 호출 시 다음 단계를 수행한다:

  1. oldEnv실행 중인 실행 컨텍스트(running execution context)의 LexicalEnvironment로 한다.
  2. uninitializedBoundNames가 비어 있지 않으면,
    1. Assert: uninitializedBoundNames에 중복 항목이 없어야 한다.
    2. newEnvNewDeclarativeEnvironment(oldEnv)로 한다.
    3. uninitializedBoundNames의 각 문자열 name에 대해,
      1. newEnv.CreateMutableBinding(name, false)을 수행한다.
    4. 실행 중인 실행 컨텍스트의 LexicalEnvironment를 newEnv로 설정한다.
  3. exprRefCompletion(Evaluation of expr)의 결과로 한다.
  4. 실행 중인 실행 컨텍스트의 LexicalEnvironment를 oldEnv로 설정한다.
  5. exprValue를 ? GetValue(? exprRef)의 결과로 한다.
  6. iterationKindenumerate이면,
    1. exprValueundefined 또는 null이면,
      1. Completion Record { [[Type]]: break, [[Value]]: empty, [[Target]]: empty }를 반환한다.
    2. obj를 ! ToObject(exprValue)로 한다.
    3. iteratorEnumerateObjectProperties(obj)의 결과로 한다.
    4. nextMethod를 ! GetV(iterator, "next")의 결과로 한다.
    5. 이터레이터 레코드(Iterator Record) { [[Iterator]]: iterator, [[NextMethod]]: nextMethod, [[Done]]: false }를 반환한다.
  7. 그 외에는,
    1. Assert: iterationKinditerate 또는 async-iterate이어야 한다.
    2. iterationKindasync-iterate이면 iteratorKindasync로 한다.
    3. 그 외에는 iteratorKindsync로 한다.
    4. Return ? GetIterator(exprValue, iteratorKind).

14.7.5.7 ForIn/OfBodyEvaluation ( lhs, stmt, iteratorRecord, iterationKind, lhsKind, labelSet [ , iteratorKind ] )

추상 연산 ForIn/OfBodyEvaluation은 lhs (파스 노드(Parse Node)), stmt (Statement 파스 노드(Parse Node)), iteratorRecord (이터레이터 레코드(Iterator Record)), iterationKind (enumerate 또는 iterate), lhsKind (assignment, var-binding, 또는 lexical-binding), labelSet (문자열의 리스트(List)), 그리고 선택적 인수 iteratorKind (sync 또는 async)를 인수로 받고, 정상 완료(normal completion)ECMAScript 언어 값 또는 비정상 완료(abrupt completion)를 반환한다. 호출 시 다음 단계를 수행한다:

  1. iteratorKind가 주어지지 않았다면, iteratorKindsync로 설정한다.
  2. oldEnv실행 중인 실행 컨텍스트(running execution context)의 LexicalEnvironment로 한다.
  3. Vundefined로 한다.
  4. destructuringIsDestructuring of lhs의 결과로 한다.
  5. destructuringtrue이고 lhsKindassignment이면,
    1. Assert: lhsLeftHandSideExpression이어야 한다.
    2. assignmentPatternlhscover하는 AssignmentPattern으로 한다.
  6. 반복한다,
    1. nextResult를 ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]])의 결과로 한다.
    2. iteratorKindasync이면, nextResult를 ? Await(nextResult)의 결과로 설정한다.
    3. nextResult객체가 아니면, TypeError 예외를 발생시킨다.
    4. done을 ? IteratorComplete(nextResult)의 결과로 한다.
    5. donetrue이면 V를 반환한다.
    6. nextValue를 ? IteratorValue(nextResult)의 결과로 한다.
    7. lhsKindassignment 또는 var-binding이면,
      1. destructuringtrue이면,
        1. lhsKindassignment이면,
          1. statusCompletion(DestructuringAssignmentEvaluation of assignmentPatternnextValue 인수를 넘겨 수행한 결과)로 한다.
        2. 그 외에는,
          1. Assert: lhsKindvar-binding이어야 한다.
          2. Assert: lhsForBinding이어야 한다.
          3. statusCompletion(BindingInitialization of lhsnextValueundefined를 인수로 넘겨 수행한 결과)로 한다.
      2. 그 외에는,
        1. lhsRefCompletion(Evaluation of lhs)의 결과로 한다. (이것은 반복적으로 평가될 수 있다.)
        2. lhsKindassignment이고 AssignmentTargetType of lhsweb-compat이면, ReferenceError 예외를 발생시킨다.
        3. lhsRef비정상 완료이면,
          1. statuslhsRef로 한다.
        4. 그 외에는,
          1. statusCompletion(PutValue(lhsRef.[[Value]], nextValue))의 결과로 한다.
    8. 그 외에는,
      1. Assert: lhsKindlexical-binding이어야 한다.
      2. Assert: lhsForDeclaration이어야 한다.
      3. iterationEnvNewDeclarativeEnvironment(oldEnv)로 한다.
      4. ForDeclarationBindingInstantiation of lhsiterationEnv 인수를 넘겨 수행한다.
      5. 실행 중인 실행 컨텍스트의 LexicalEnvironment를 iterationEnv로 설정한다.
      6. destructuringtrue이면,
        1. statusCompletion(ForDeclarationBindingInitialization of lhsnextValueiterationEnv를 인수로 넘겨 수행한 결과)로 한다.
      7. 그 외에는,
        1. Assert: lhs는 단일 이름을 바인딩한다.
        2. lhsNameBoundNames of lhs의 유일한 요소로 한다.
        3. lhsRef를 ! ResolveBinding(lhsName)로 한다.
        4. statusCompletion(InitializeReferencedBinding(lhsRef, nextValue))의 결과로 한다.
    9. status비정상 완료이면,
      1. 실행 중인 실행 컨텍스트의 LexicalEnvironment를 oldEnv로 설정한다.
      2. iteratorKindasync이면, ? AsyncIteratorClose(iteratorRecord, status)를 반환한다.
      3. iterationKindenumerate이면,
        1. status를 반환한다.
      4. 그 외에는,
        1. Assert: iterationKinditerate이어야 한다.
        2. IteratorClose(iteratorRecord, status)를 반환한다.
    10. resultCompletion(Evaluation of stmt)의 결과로 한다.
    11. 실행 중인 실행 컨텍스트의 LexicalEnvironment를 oldEnv로 설정한다.
    12. LoopContinues(result, labelSet)이 false이면,
      1. iterationKindenumerate이면,
        1. UpdateEmpty(result, V)를 반환한다.
      2. 그 외에는,
        1. Assert: iterationKinditerate이어야 한다.
        2. statusCompletion(UpdateEmpty(result, V))의 결과로 한다.
        3. iteratorKindasync이면, ? AsyncIteratorClose(iteratorRecord, status)를 반환한다.
        4. IteratorClose(iteratorRecord, status)를 반환한다.
    13. result.[[Value]]empty가 아니면, Vresult.[[Value]]를 설정한다.

14.7.5.8 런타임 의미론: 평가

BindingIdentifier : Identifier yield await
  1. bindingIdBindingIdentifierStringValue로 한다.
  2. ResolveBinding(bindingId)를 반환한다.

14.7.5.9 EnumerateObjectProperties ( O )

추상 연산 EnumerateObjectProperties는 인수 O (객체)를 받고, 이터레이터 객체(iterator object)를 반환한다. 호출 시 다음 단계를 수행한다:

  1. 이터레이터 객체를 반환한다. 이 객체의 next 메서드는 O의 열거 가능한 프로퍼티의 모든 문자열 키를 순회한다. 이터레이터 객체는 ECMAScript 코드에서 직접 접근할 수 없다. 프로퍼티 열거의 메커니즘과 순서는 명시되어 있지 않지만, 아래 명시된 규칙을 따라야 한다.

이터레이터throwreturn 메서드는 null이며, 호출되지 않는다. 이터레이터next 메서드는 객체의 프로퍼티가 프로퍼티 키로 반환되어야 하는지 판별한다. 반환되는 프로퍼티 키에는 심볼(Symbol) 키가 포함되지 않는다. 대상 객체의 프로퍼티는 열거 도중 삭제될 수 있다. 이터레이터next 메서드가 처리하기 전에 삭제된 프로퍼티는 무시된다. 열거 도중 새 프로퍼티가 추가된 경우, 새로 추가된 프로퍼티가 반드시 열거될 필요는 없다. 프로퍼티 이름은 어떤 열거에서도 이터레이터next 메서드에서 최대 한 번만 반환된다.

대상 객체의 프로퍼티를 열거할 때, 프로토타입, 프로토타입의 프로토타입 등도 재귀적으로 열거 대상에 포함된다. 단, 프로토타입의 프로퍼티가 이터레이터next 메서드에 의해 이미 처리된 이름과 같은 경우는 건너뛴다. 프로토타입 객체의 [[Enumerable]] 속성 값은 이미 처리된 프로퍼티 판정에 고려되지 않는다. 프로토타입 객체의 열거 가능한 프로퍼티 이름은 EnumerateObjectProperties를 해당 프로토타입 객체에 대해 호출하여 얻어야 한다. EnumerateObjectProperties는 대상 객체의 [[OwnPropertyKeys]] 내부 메서드를 호출하여 자신의 프로퍼티 키를 얻어야 한다. 프로퍼티 속성 정보는 [[GetOwnProperty]] 내부 메서드를 호출하여 얻어야 한다.

또한 O나 그 프로토타입 체인의 어떤 객체도 프록시 이색 객체(Proxy exotic object), TypedArray, 모듈 네임스페이스 이색 객체(module namespace exotic object), 또는 구현체가 제공하는 이색 객체(exotic object)가 아닌 경우, 이터레이터이터레이터와 동일하게 동작해야 하며, 이는 CreateForInIterator(O)가 반환하는 이터레이터와 동일하다. 단, 다음 조건 중 하나가 발생할 때까지이다:

  • O나 그 프로토타입 체인의 객체의 [[Prototype]] 내부 슬롯의 값이 변경됨
  • O나 그 프로토타입 체인의 객체에서 프로퍼티가 제거됨
  • O의 프로토타입 체인의 객체에 프로퍼티가 추가됨
  • O나 그 프로토타입 체인의 객체의 프로퍼티의 [[Enumerable]] 속성 값이 변경됨
참고 1

ECMAScript 구현체는 14.7.5.10.2.1의 알고리즘을 직접 구현할 필요는 없다. 위 단락의 제약조건이 위반되지 않는 한, 어떤 동작도 이 알고리즘과 다르지 않으면 된다.

아래는 이러한 규칙을 준수하는 ECMAScript generator 함수의 정보적 정의이다:

function* EnumerateObjectProperties(obj) {
  const visited = new Set();
  for (const key of Reflect.ownKeys(obj)) {
    if (typeof key === "symbol") continue;
    const desc = Reflect.getOwnPropertyDescriptor(obj, key);
    if (desc) {
      visited.add(key);
      if (desc.enumerable) yield key;
    }
  }
  const proto = Reflect.getPrototypeOf(obj);
  if (proto === null) return;
  for (const protoKey of EnumerateObjectProperties(proto)) {
    if (!visited.has(protoKey)) yield protoKey;
  }
}
참고 2
이색 객체(exotic objects)의 목록은, 구현체들이 전통적으로 이러한 경우에 대해 동작이 달랐고, 다른 경우에는 일치한다는 점에 근거하여 결정되었다. 이 경우에는 CreateForInIterator와의 일치가 요구되지 않는다.

14.7.5.10 for-in 이터레이터 객체

for-in 이터레이터는 특정 객체에 대한 특정 반복(iteration)을 나타내는 객체이다. for-in 이터레이터 객체는 ECMAScript 코드에서 직접 접근할 수 없으며, EnumerateObjectProperties의 동작을 설명하기 위한 목적으로만 존재한다.

14.7.5.10.1 CreateForInIterator ( object )

추상 연산 CreateForInIterator는 인수 object (객체)를 받고, for-in 이터레이터를 반환한다. 이 연산은 object의 자신의 및 상속받은 열거 가능한 문자열 프로퍼티를 특정 순서로 순회하는 for-in 이터레이터 객체를 생성한다. 호출 시 다음 단계를 수행한다:

  1. iteratorOrdinaryObjectCreate(%ForInIteratorPrototype%, « [[Object]], [[ObjectWasVisited]], [[VisitedKeys]], [[RemainingKeys]] »)로 한다.
  2. iterator.[[Object]]object를 설정한다.
  3. iterator.[[ObjectWasVisited]]false를 설정한다.
  4. iterator.[[VisitedKeys]]에 새로운 빈 리스트(List)를 설정한다.
  5. iterator.[[RemainingKeys]]에 새로운 빈 리스트(List)를 설정한다.
  6. iterator를 반환한다.

14.7.5.10.2 %ForInIteratorPrototype% 객체

%ForInIteratorPrototype% 객체:

14.7.5.10.2.1 %ForInIteratorPrototype%.next ( )

  1. Othis 값으로 한다.
  2. Assert: O객체이다.
  3. Assert: Ofor-in 이터레이터 인스턴스의 모든 내부 슬롯을 가진다 (14.7.5.10.3).
  4. objectO.[[Object]]로 한다.
  5. 반복한다,
    1. O.[[ObjectWasVisited]]false이면,
      1. keys를 ? object.[[OwnPropertyKeys]]()로 한다.
      2. keys의 각 요소 key에 대해,
        1. key문자열(String)이면,
          1. keyO.[[RemainingKeys]]에 추가한다.
      3. O.[[ObjectWasVisited]]true를 설정한다.
    2. O.[[RemainingKeys]]가 비어있지 않은 동안 반복한다,
      1. rO.[[RemainingKeys]]의 첫 번째 요소로 한다.
      2. O.[[RemainingKeys]]의 첫 번째 요소를 제거한다.
      3. O.[[VisitedKeys]]r이 없다면,
        1. desc를 ? object.[[GetOwnProperty]](r)로 한다.
        2. descundefined가 아니면,
          1. rO.[[VisitedKeys]]에 추가한다.
          2. desc.[[Enumerable]]true이면, CreateIteratorResultObject(r, false)를 반환한다.
    3. object를 ? object.[[GetPrototypeOf]]()로 한다.
    4. O.[[Object]]object를 설정한다.
    5. O.[[ObjectWasVisited]]false를 설정한다.
    6. objectnull이면, CreateIteratorResultObject(undefined, true)를 반환한다.

14.7.5.10.3 for-in 이터레이터 인스턴스의 프로퍼티

for-in 이터레이터 인스턴스는 일반 객체(ordinary objects)이며, %ForInIteratorPrototype% 내재 객체를 상속한다. for-in 이터레이터 인스턴스는 표 38에 나열된 내부 슬롯으로 생성된다.

표 38: for-in 이터레이터 인스턴스의 내부 슬롯
내부 슬롯 타입 설명
[[Object]] 객체 반복 대상이 되는 객체 값.
[[ObjectWasVisited]] 불리언(Boolean) true이면 이터레이터[[Object]]에서 [[OwnPropertyKeys]]를 호출한 적이 있고, 그렇지 않으면 false이다.
[[VisitedKeys]] 문자열의 리스트(List) 현재까지 이 이터레이터에서 반환한 값들.
[[RemainingKeys]] 문자열의 리스트(List) 현재 객체에서 프로토타입의 프로퍼티(프로토타입이 null이 아닌 경우)로 넘어가기 전에 반환해야 할 값들.

14.8 continue

구문

ContinueStatement[Yield, Await] : continue ; continue [여기에 LineTerminator가 없음] LabelIdentifier[?Yield, ?Await] ;

14.8.1 정적 의미론: 초기 에러

ContinueStatement : continue ; continue LabelIdentifier ;
  • ContinueStatement가 함수나 static 초기화 블록 경계를 넘지 않고 직접적으로 또는 간접적으로 IterationStatement 내에 중첩되어 있지 않으면 구문 오류이다.

14.8.2 런타임 의미론: 평가

ContinueStatement : continue ;
  1. Completion Record { [[Type]]: continue, [[Value]]: empty, [[Target]]: empty }를 반환한다.
ContinueStatement : continue LabelIdentifier ;
  1. labelLabelIdentifierStringValue로 한다.
  2. Completion Record { [[Type]]: continue, [[Value]]: empty, [[Target]]: label }를 반환한다.

14.9 break

구문

BreakStatement[Yield, Await] : break ; break [여기에 LineTerminator가 없음] LabelIdentifier[?Yield, ?Await] ;

14.9.1 정적 의미론: 초기 에러

BreakStatement : break ;

14.9.2 런타임 의미론: 평가

BreakStatement : break ;
  1. Completion Record { [[Type]]: break, [[Value]]: empty, [[Target]]: empty }를 반환한다.
BreakStatement : break LabelIdentifier ;
  1. labelLabelIdentifierStringValue로 한다.
  2. Completion Record { [[Type]]: break, [[Value]]: empty, [[Target]]: label }를 반환한다.

14.10 return

구문

ReturnStatement[Yield, Await] : return ; return [여기에 LineTerminator가 없음] Expression[+In, ?Yield, ?Await] ; 참고

return 문은 함수의 실행을 중단시키고, 대부분의 경우 호출자에게 값을 반환한다. Expression이 생략되면 반환 값은 undefined이다. 그렇지 않으면 반환 값은 Expression의 값이다. return 문은 주변 문맥에 따라 실제로는 호출자에게 값을 반환하지 않을 수도 있다. 예를 들어 try 블록에서 return 문이 실행될 때는 Completion Recordfinally 블록 평가 중에 다른 Completion Record로 대체될 수 있다.

14.10.1 런타임 의미론: 평가

ReturnStatement : return ;
  1. ReturnCompletion(undefined)를 반환한다.
ReturnStatement : return Expression ;
  1. exprRef를 ? Evaluation of Expression의 결과로 한다.
  2. exprValue를 ? GetValue(exprRef)의 결과로 한다.
  3. GetGeneratorKind()가 async이면 exprValue를 ? Await(exprValue)의 결과로 한다.
  4. ReturnCompletion(exprValue)를 반환한다.

14.11 with

참고 1

레거시 with 문의 사용은 새로운 ECMAScript 코드에서 지양해야 한다. 엄격 모드 코드비엄격 코드 모두에서 허용되는 구조 분해 할당과 같은 대안을 고려하라.

구문

WithStatement[Yield, Await, Return] : with ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] 참고 2

with 문은 계산된 객체에 대한 객체 환경 레코드실행 중인 실행 컨텍스트의 렉시컬 환경에 추가한다. 그런 다음 이 확장된 렉시컬 환경을 사용하여 문을 실행한다. 마지막으로 원래의 렉시컬 환경으로 복원한다.

14.11.1 정적 의미론: 초기 에러

WithStatement : with ( Expression ) Statement 참고

두 번째 규칙은 B.3.1에 명시된 확장이 구현된 경우에만 적용된다.

14.11.2 런타임 의미론: 평가

WithStatement : with ( Expression ) Statement
  1. val을 ? Evaluation of Expression의 결과로 한다.
  2. obj를 ? ToObject(? GetValue(val))의 결과로 한다.
  3. oldEnv실행 중인 실행 컨텍스트의 LexicalEnvironment로 한다.
  4. newEnvNewObjectEnvironment(obj, true, oldEnv)로 한다.
  5. 실행 중인 실행 컨텍스트의 LexicalEnvironment를 newEnv로 설정한다.
  6. CCompletion(Evaluation of Statement)의 결과로 한다.
  7. 실행 중인 실행 컨텍스트의 LexicalEnvironment를 oldEnv로 설정한다.
  8. UpdateEmpty(C, undefined)를 반환한다.
참고

내포된 Statement를 정상적으로 또는 비정상 완료나 예외로 벗어나더라도, 렉시컬 환경은 항상 원래 상태로 복원된다.

14.12 switch

구문

SwitchStatement[Yield, Await, Return] : switch ( Expression[+In, ?Yield, ?Await] ) CaseBlock[?Yield, ?Await, ?Return] CaseBlock[Yield, Await, Return] : { CaseClauses[?Yield, ?Await, ?Return]opt } { CaseClauses[?Yield, ?Await, ?Return]opt DefaultClause[?Yield, ?Await, ?Return] CaseClauses[?Yield, ?Await, ?Return]opt } CaseClauses[Yield, Await, Return] : CaseClause[?Yield, ?Await, ?Return] CaseClauses[?Yield, ?Await, ?Return] CaseClause[?Yield, ?Await, ?Return] CaseClause[Yield, Await, Return] : case Expression[+In, ?Yield, ?Await] : StatementList[?Yield, ?Await, ?Return]opt DefaultClause[Yield, Await, Return] : default : StatementList[?Yield, ?Await, ?Return]opt

14.12.1 정적 의미론: 초기 에러

SwitchStatement : switch ( Expression ) CaseBlock

14.12.2 런타임 의미론: CaseBlockEvaluation

구문 지시 연산 CaseBlockEvaluation은 인수 input (ECMAScript 언어 값)을 받고, 정상 완료ECMAScript 언어 값 또는 비정상 완료를 반환한다. 다음 생성식에 대해 조각별로 정의된다:

CaseBlock : { }
  1. undefined를 반환한다.
CaseBlock : { CaseClauses }
  1. Vundefined로 한다.
  2. ACaseClausesCaseClause 항목들의 소스 텍스트 순서 리스트로 한다.
  3. foundfalse로 한다.
  4. A의 각 CaseClause C에 대해, 다음을 수행한다:
    1. foundfalse이면,
      1. found를 ? CaseClauseIsSelected(C, input)의 결과로 설정한다.
    2. foundtrue이면,
      1. RCompletion(Evaluation of C)의 결과로 한다.
      2. R.[[Value]]empty가 아니면, VR.[[Value]]를 설정한다.
      3. R비정상 완료이면, ? UpdateEmpty(R, V)를 반환한다.
  5. V를 반환한다.
CaseBlock : { CaseClausesopt DefaultClause CaseClausesopt }
  1. Vundefined로 한다.
  2. 첫 번째 CaseClauses가 존재하면,
    1. A를 첫 번째 CaseClausesCaseClause 항목들의 소스 텍스트 순서 리스트로 한다.
  3. 그 외에는,
    1. A를 새로운 빈 리스트로 한다.
  4. foundfalse로 한다.
  5. A의 각 CaseClause C에 대해, 다음을 수행한다:
    1. foundfalse이면,
      1. found를 ? CaseClauseIsSelected(C, input)의 결과로 설정한다.
    2. foundtrue이면,
      1. RCompletion(Evaluation of C)의 결과로 한다.
      2. R.[[Value]]empty가 아니면, VR.[[Value]]를 설정한다.
      3. R비정상 완료이면, ? UpdateEmpty(R, V)를 반환한다.
  6. foundInBfalse로 한다.
  7. 두 번째 CaseClauses가 존재하면,
    1. B를 두 번째 CaseClausesCaseClause 항목들의 소스 텍스트 순서 리스트로 한다.
  8. 그 외에는,
    1. B를 새로운 빈 리스트로 한다.
  9. foundfalse이면,
    1. B의 각 CaseClause C에 대해, 다음을 수행한다:
      1. foundInBfalse이면,
        1. foundInB를 ? CaseClauseIsSelected(C, input)의 결과로 설정한다.
      2. foundInBtrue이면,
        1. RCompletion(Evaluation of CaseClause C)의 결과로 한다.
        2. R.[[Value]]empty가 아니면, VR.[[Value]]를 설정한다.
        3. R비정상 완료이면, ? UpdateEmpty(R, V)를 반환한다.
  10. foundInBtrue이면 V를 반환한다.
  11. defaultRCompletion(Evaluation of DefaultClause)의 결과로 한다.
  12. defaultR.[[Value]]empty가 아니면, VdefaultR.[[Value]]를 설정한다.
  13. defaultR비정상 완료이면, ? UpdateEmpty(defaultR, V)를 반환한다.
  14. 참고: 다음은 두 번째 CaseClauses의 또 다른 완전 반복이다.
  15. B의 각 CaseClause C에 대해, 다음을 수행한다:
    1. RCompletion(Evaluation of CaseClause C)의 결과로 한다.
    2. R.[[Value]]empty가 아니면, VR.[[Value]]를 설정한다.
    3. R비정상 완료이면, ? UpdateEmpty(R, V)를 반환한다.
  16. V를 반환한다.

14.12.3 CaseClauseIsSelected ( C, input )

추상 연산 CaseClauseIsSelected는 인수 C (CaseClause 파스 노드(Parse Node))와 input (ECMAScript 언어 값)을 받고, 정상 완료로 불리언(Boolean) 또는 비정상 완료를 반환한다. 이 연산은 Cinput과 일치하는지 판단한다. 호출 시 다음 단계를 수행한다:

  1. Assert: C는 다음 생성식의 인스턴스이다: CaseClause : case Expression : StatementListopt .
  2. exprRefCExpression에 대해 ? Evaluation의 결과로 한다.
  3. clauseSelector를 ? GetValue(exprRef)의 결과로 한다.
  4. IsStrictlyEqual(input, clauseSelector)를 반환한다.
참고

이 연산은 CStatementList(있는 경우)를 실행하지 않는다. CaseBlock 알고리즘은 이 반환 값을 사용하여 어느 StatementList부터 실행을 시작할지 결정한다.

14.12.4 런타임 의미론: 평가

SwitchStatement : switch ( Expression ) CaseBlock
  1. exprRef를 ? Evaluation of Expression의 결과로 한다.
  2. switchValue를 ? GetValue(exprRef)의 결과로 한다.
  3. oldEnv실행 중인 실행 컨텍스트의 LexicalEnvironment로 한다.
  4. blockEnvNewDeclarativeEnvironment(oldEnv)로 한다.
  5. BlockDeclarationInstantiation(CaseBlock, blockEnv)를 수행한다.
  6. 실행 중인 실행 컨텍스트의 LexicalEnvironment를 blockEnv로 설정한다.
  7. RCompletion(CaseBlockEvaluation of CaseBlockswitchValue 인수를 넘겨 수행한 결과)로 한다.
  8. 실행 중인 실행 컨텍스트의 LexicalEnvironment를 oldEnv로 설정한다.
  9. R을 반환한다.
참고

SwitchStatement에서 제어가 어떻게 빠져나가든, LexicalEnvironment는 항상 원래 상태로 복원된다.

CaseClause : case Expression :
  1. empty를 반환한다.
CaseClause : case Expression : StatementList
  1. Evaluation of StatementList의 결과를 반환한다.
DefaultClause : default :
  1. empty를 반환한다.
DefaultClause : default : StatementList
  1. Evaluation of StatementList의 결과를 반환한다.

14.13 레이블문

구문

LabelledStatement[Yield, Await, Return] : LabelIdentifier[?Yield, ?Await] : LabelledItem[?Yield, ?Await, ?Return] LabelledItem[Yield, Await, Return] : Statement[?Yield, ?Await, ?Return] FunctionDeclaration[?Yield, ?Await, ~Default] 참고

Statement는 레이블로 접두사를 붙일 수 있다. 레이블문은 레이블이 붙은 breakcontinue 문과 함께 사용할 때만 쓰인다. ECMAScript에는 goto 문이 없다. StatementLabelledStatement의 일부일 수 있으며, 이는 다시 LabelledStatement의 일부일 수도 있고, 계속 반복된다. 이렇게 도입된 레이블들은 개별 문들의 의미를 설명할 때 "현재 레이블 집합(current label set)"이라고 한다.

14.13.1 정적 의미론: 초기 에러

LabelledItem : FunctionDeclaration
  • 이 생성식에 의해 소스 텍스트가 매치되면 구문 오류이다.
참고

이 규칙에 대한 대안 정의는 B.3.1에 제공되어 있다.

14.13.2 정적 의미론: IsLabelledFunction ( stmt )

추상 연산 IsLabelledFunction은 인수 stmt (Statement 파스 노드(Parse Node))를 받고, Boolean을 반환한다. 호출 시 다음 단계를 수행한다:

  1. stmtLabelledStatement가 아니면 false를 반환한다.
  2. itemstmtLabelledItem로 한다.
  3. item LabelledItem : FunctionDeclaration 이면 true를 반환한다.
  4. subStmtitemStatement로 한다.
  5. IsLabelledFunction(subStmt)의 결과를 반환한다.

14.13.3 런타임 의미론: 평가

LabelledStatement : LabelIdentifier : LabelledItem
  1. LabelledEvaluation of 이 LabelledStatement 에 인수 « »를 넘겨서 그 결과를 반환한다.

14.13.4 런타임 의미론: LabelledEvaluation

구문 지시 연산 LabelledEvaluation은 인수 labelSet (문자열의 리스트(List))를 받고, 정상 완료(ECMAScript 언어 값 또는 empty) 또는 비정상 완료를 반환한다. 다음 생성식에 대해 조각별로 정의된다:

BreakableStatement : IterationStatement
  1. stmtResultCompletion(LoopEvaluation of IterationStatementlabelSet 인수를 넘겨서 수행한 결과)로 한다.
  2. stmtResultbreak 완료(break completion)이면,
    1. stmtResult.[[Target]]empty이면,
      1. stmtResult.[[Value]]empty이면, stmtResultNormalCompletion(undefined)로 설정한다.
      2. 그 외에는, stmtResultNormalCompletion(stmtResult.[[Value]])로 설정한다.
  3. stmtResult를 반환한다.
BreakableStatement : SwitchStatement
  1. stmtResultCompletion(Evaluation of SwitchStatement)의 결과로 한다.
  2. stmtResultbreak 완료(break completion)이면,
    1. stmtResult.[[Target]]empty이면,
      1. stmtResult.[[Value]]empty이면, stmtResultNormalCompletion(undefined)로 설정한다.
      2. 그 외에는, stmtResultNormalCompletion(stmtResult.[[Value]])로 설정한다.
  3. stmtResult를 반환한다.
참고 1

BreakableStatement는 레이블이 없는 BreakStatement로 탈출할 수 있는 문이다.

LabelledStatement : LabelIdentifier : LabelledItem
  1. labelLabelIdentifierStringValue로 한다.
  2. newLabelSetlabelSet과 « label »의 리스트 연결(list-concatenation)로 한다.
  3. stmtResultCompletion(LabelledEvaluation of LabelledItemnewLabelSet 인수를 넘겨서 수행한 결과)로 한다.
  4. stmtResultbreak 완료(break completion)이고 stmtResult.[[Target]]label이면,
    1. stmtResultNormalCompletion(stmtResult.[[Value]])로 설정한다.
  5. stmtResult를 반환한다.
LabelledItem : FunctionDeclaration
  1. Evaluation of FunctionDeclaration의 결과를 반환한다.
Statement : BlockStatement VariableStatement EmptyStatement ExpressionStatement IfStatement ContinueStatement BreakStatement ReturnStatement WithStatement ThrowStatement TryStatement DebuggerStatement
  1. Evaluation of Statement의 결과를 반환한다.
참고 2

Statement의 두 가지 생성식만이 LabelledEvaluation에서 특별한 의미를 가진다: BreakableStatementLabelledStatement.

14.14 throw

구문

ThrowStatement[Yield, Await] : throw [여기에 LineTerminator가 없음] Expression[+In, ?Yield, ?Await] ;

14.14.1 런타임 의미론: 평가

ThrowStatement : throw Expression ;
  1. exprRef를 ? Evaluation of Expression의 결과로 한다.
  2. exprValue를 ? GetValue(exprRef)의 결과로 한다.
  3. ThrowCompletion(exprValue)를 반환한다.

14.15 try

구문

TryStatement[Yield, Await, Return] : try Block[?Yield, ?Await, ?Return] Catch[?Yield, ?Await, ?Return] try Block[?Yield, ?Await, ?Return] Finally[?Yield, ?Await, ?Return] try Block[?Yield, ?Await, ?Return] Catch[?Yield, ?Await, ?Return] Finally[?Yield, ?Await, ?Return] Catch[Yield, Await, Return] : catch ( CatchParameter[?Yield, ?Await] ) Block[?Yield, ?Await, ?Return] catch Block[?Yield, ?Await, ?Return] Finally[Yield, Await, Return] : finally Block[?Yield, ?Await, ?Return] CatchParameter[Yield, Await] : BindingIdentifier[?Yield, ?Await] BindingPattern[?Yield, ?Await] 참고

try 문은 런타임 오류나 throw 문과 같은 예외 상황이 발생할 수 있는 코드 블록을 감싼다. catch 절은 예외 처리 코드를 제공한다. catch 절이 예외를 포착하면, 그 CatchParameter가 해당 예외에 바인딩된다.

14.15.1 정적 의미론: 초기 에러

Catch : catch ( CatchParameter ) Block 참고

이 생성식에 대한 대안 정적 의미론B.3.4에 제시되어 있다.

14.15.2 런타임 의미론: CatchClauseEvaluation

구문 지시 연산 CatchClauseEvaluation은 인수 thrownValue (ECMAScript 언어 값)을 받고, 정상 완료(ECMAScript 언어 값 또는 empty) 또는 비정상 완료를 반환한다. 다음 생성식에 대해 조각별로 정의된다:

Catch : catch ( CatchParameter ) Block
  1. oldEnv실행 중인 실행 컨텍스트의 LexicalEnvironment로 한다.
  2. catchEnvNewDeclarativeEnvironment(oldEnv)로 한다.
  3. CatchParameterBoundNames의 각 요소 argName에 대해,
    1. catchEnv.CreateMutableBinding(argName, false)을 수행한다.
  4. 실행 중인 실행 컨텍스트의 LexicalEnvironment를 catchEnv로 설정한다.
  5. statusCompletion(BindingInitialization of CatchParameterthrownValuecatchEnv 인수를 넘겨서 수행한 결과)로 한다.
  6. status비정상 완료이면,
    1. 실행 중인 실행 컨텍스트의 LexicalEnvironment를 oldEnv로 설정한다.
    2. status를 반환한다.
  7. BCompletion(Evaluation of Block)의 결과로 한다.
  8. 실행 중인 실행 컨텍스트의 LexicalEnvironment를 oldEnv로 설정한다.
  9. B를 반환한다.
Catch : catch Block
  1. Evaluation of Block의 결과를 반환한다.
참고

Block에서 제어가 어떻게 빠져나가든, LexicalEnvironment는 항상 원래 상태로 복원된다.

14.15.3 런타임 의미론: 평가

TryStatement : try Block Catch
  1. BCompletion(Evaluation of Block)의 결과로 한다.
  2. Bthrow 완료(throw completion)이면, CCompletion(CatchClauseEvaluation of CatchB.[[Value]] 인수를 넘겨서 수행한 결과)로 한다.
  3. 그 외에는, CB로 한다.
  4. UpdateEmpty(C, undefined)를 반환한다.
TryStatement : try Block Finally
  1. BCompletion(Evaluation of Block)의 결과로 한다.
  2. FCompletion(Evaluation of Finally)의 결과로 한다.
  3. F정상 완료(normal completion)이면, FB로 설정한다.
  4. UpdateEmpty(F, undefined)를 반환한다.
TryStatement : try Block Catch Finally
  1. BCompletion(Evaluation of Block)의 결과로 한다.
  2. Bthrow 완료(throw completion)이면, CCompletion(CatchClauseEvaluation of CatchB.[[Value]] 인수를 넘겨서 수행한 결과)로 한다.
  3. 그 외에는, CB로 한다.
  4. FCompletion(Evaluation of Finally)의 결과로 한다.
  5. F정상 완료(normal completion)이면, FC로 설정한다.
  6. UpdateEmpty(F, undefined)를 반환한다.

14.16 debugger

구문

DebuggerStatement : debugger ;

14.16.1 런타임 의미론: 평가

참고

DebuggerStatement를 평가하면 구현체가 디버거에서 실행되는 경우 중단점(breakpoint)을 발생시킬 수 있다. 디버거가 없거나 활성화되어 있지 않으면 이 문은 관찰 가능한 효과가 없다.

DebuggerStatement : debugger ;
  1. 구현 정의 디버깅 기능이 사용 가능하고 활성화된 경우,
    1. 구현 정의 디버깅 동작을 수행한다.
    2. 새로운 구현 정의 Completion Record를 반환한다.
  2. 그 외에는,
    1. empty를 반환한다.

15 ECMAScript 언어: 함수와 클래스

참고

여러 ECMAScript 언어 요소들은 ECMAScript 함수 객체 (10.2)의 생성을 야기한다. 이러한 함수의 Evaluation[[Call]] 내부 메서드의 실행(10.2.1)으로 시작한다.

15.1 매개변수 목록

구문

UniqueFormalParameters[Yield, Await] : FormalParameters[?Yield, ?Await] FormalParameters[Yield, Await] : [비어 있음] FunctionRestParameter[?Yield, ?Await] FormalParameterList[?Yield, ?Await] FormalParameterList[?Yield, ?Await] , FormalParameterList[?Yield, ?Await] , FunctionRestParameter[?Yield, ?Await] FormalParameterList[Yield, Await] : FormalParameter[?Yield, ?Await] FormalParameterList[?Yield, ?Await] , FormalParameter[?Yield, ?Await] FunctionRestParameter[Yield, Await] : BindingRestElement[?Yield, ?Await] FormalParameter[Yield, Await] : BindingElement[?Yield, ?Await]

15.1.1 정적 의미론: 초기 에러

UniqueFormalParameters : FormalParameters FormalParameters : FormalParameterList 참고

같은 BindingIdentifierFormalParameterList에 여러 번 등장하는 것은, 함수가 단순 매개변수 목록을 가지고 있고 엄격 모드 코드에서 정의되지 않은 경우에만 허용된다.

15.1.2 정적 의미론: ContainsExpression

구문 지시 연산 ContainsExpression은 인수를 받지 않고 Boolean을 반환한다. 다음 생성식에 대해 조각별로 정의된다:

ObjectBindingPattern : { } { BindingRestProperty }
  1. false를 반환한다.
ObjectBindingPattern : { BindingPropertyList , BindingRestProperty }
  1. ContainsExpression of BindingPropertyList를 반환한다.
ArrayBindingPattern : [ Elisionopt ]
  1. false를 반환한다.
ArrayBindingPattern : [ Elisionopt BindingRestElement ]
  1. ContainsExpression of BindingRestElement를 반환한다.
ArrayBindingPattern : [ BindingElementList , Elisionopt ]
  1. ContainsExpression of BindingElementList를 반환한다.
ArrayBindingPattern : [ BindingElementList , Elisionopt BindingRestElement ]
  1. hasContainsExpression of BindingElementList로 한다.
  2. hastrue이면 true를 반환한다.
  3. ContainsExpression of BindingRestElement를 반환한다.
BindingPropertyList : BindingPropertyList , BindingProperty
  1. hasContainsExpression of BindingPropertyList로 한다.
  2. hastrue이면 true를 반환한다.
  3. ContainsExpression of BindingProperty를 반환한다.
BindingElementList : BindingElementList , BindingElisionElement
  1. hasContainsExpression of BindingElementList로 한다.
  2. hastrue이면 true를 반환한다.
  3. ContainsExpression of BindingElisionElement를 반환한다.
BindingElisionElement : Elisionopt BindingElement
  1. ContainsExpression of BindingElement를 반환한다.
BindingProperty : PropertyName : BindingElement
  1. hasIsComputedPropertyKey of PropertyName로 한다.
  2. hastrue이면 true를 반환한다.
  3. ContainsExpression of BindingElement를 반환한다.
BindingElement : BindingPattern Initializer
  1. true를 반환한다.
SingleNameBinding : BindingIdentifier
  1. false를 반환한다.
SingleNameBinding : BindingIdentifier Initializer
  1. true를 반환한다.
BindingRestElement : ... BindingIdentifier
  1. false를 반환한다.
BindingRestElement : ... BindingPattern
  1. ContainsExpression of BindingPattern를 반환한다.
FormalParameters : [비어 있음]
  1. false를 반환한다.
FormalParameters : FormalParameterList , FunctionRestParameter
  1. ContainsExpression of FormalParameterListtrue이면 true를 반환한다.
  2. ContainsExpression of FunctionRestParameter를 반환한다.
FormalParameterList : FormalParameterList , FormalParameter
  1. ContainsExpression of FormalParameterListtrue이면 true를 반환한다.
  2. ContainsExpression of FormalParameter를 반환한다.
ArrowParameters : BindingIdentifier
  1. false를 반환한다.
ArrowParameters : CoverParenthesizedExpressionAndArrowParameterList
  1. formalsArrowFormalParameters로 한다. 이는 coverCoverParenthesizedExpressionAndArrowParameterList에 의해 얻어진다.
  2. ContainsExpression of formals를 반환한다.
AsyncArrowBindingIdentifier : BindingIdentifier
  1. false를 반환한다.

15.1.3 정적 의미론: IsSimpleParameterList

구문 지시 연산 IsSimpleParameterList는 인수를 받지 않고 Boolean을 반환한다. 다음 생성식에 대해 조각별로 정의된다:

BindingElement : BindingPattern
  1. false를 반환한다.
BindingElement : BindingPattern Initializer
  1. false를 반환한다.
SingleNameBinding : BindingIdentifier
  1. true를 반환한다.
SingleNameBinding : BindingIdentifier Initializer
  1. false를 반환한다.
FormalParameters : [empty]
  1. true를 반환한다.
FormalParameters : FunctionRestParameter
  1. false를 반환한다.
FormalParameters : FormalParameterList , FunctionRestParameter
  1. false를 반환한다.
FormalParameterList : FormalParameterList , FormalParameter
  1. IsSimpleParameterList of FormalParameterListfalse이면 false를 반환한다.
  2. IsSimpleParameterList of FormalParameter를 반환한다.
FormalParameter : BindingElement
  1. IsSimpleParameterList of BindingElement를 반환한다.
ArrowParameters : BindingIdentifier
  1. true를 반환한다.
ArrowParameters : CoverParenthesizedExpressionAndArrowParameterList
  1. formalsArrowFormalParameters로 한다. 이는 coverCoverParenthesizedExpressionAndArrowParameterList에 의해 얻어진다.
  2. IsSimpleParameterList of formals를 반환한다.
AsyncArrowBindingIdentifier : BindingIdentifier
  1. true를 반환한다.
CoverCallExpressionAndAsyncArrowHead : MemberExpression Arguments
  1. headAsyncArrowHead로 한다. 이는 coverCoverCallExpressionAndAsyncArrowHead에 의해 얻어진다.
  2. IsSimpleParameterList of head를 반환한다.

15.1.4 정적 의미론: HasInitializer

구문 지시 연산 HasInitializer는 인수를 받지 않고 Boolean을 반환한다. 다음 생성식에 대해 조각별로 정의된다:

BindingElement : BindingPattern
  1. false를 반환한다.
BindingElement : BindingPattern Initializer
  1. true를 반환한다.
SingleNameBinding : BindingIdentifier
  1. false를 반환한다.
SingleNameBinding : BindingIdentifier Initializer
  1. true를 반환한다.
FormalParameterList : FormalParameterList , FormalParameter
  1. HasInitializer of FormalParameterListtrue이면 true를 반환한다.
  2. HasInitializer of FormalParameter를 반환한다.

15.1.5 정적 의미론: ExpectedArgumentCount

구문 지시 연산 ExpectedArgumentCount는 인수를 받지 않고 음이 아닌 정수를 반환한다. 다음 생성식에 대해 조각별로 정의된다:

FormalParameters : [비어 있음] FunctionRestParameter
  1. 0을 반환한다.
FormalParameters : FormalParameterList , FunctionRestParameter
  1. FormalParameterListExpectedArgumentCount를 반환한다.
참고

FormalParameterList의 ExpectedArgumentCount는 나머지 매개변수 또는 첫 번째 FormalParameter가 Initializer를 가진 경우 그 왼쪽에 있는 FormalParameters의 개수이다. 초기화자가 없는 FormalParameter가 초기화자를 가진 매개변수 뒤에 오는 것은 허용되지만, 이러한 매개변수는 undefined를 기본값으로 하는 선택적 매개변수로 간주된다.

FormalParameterList : FormalParameter
  1. FormalParameterHasInitializertrue이면 0을 반환한다.
  2. 1을 반환한다.
FormalParameterList : FormalParameterList , FormalParameter
  1. countFormalParameterListExpectedArgumentCount로 한다.
  2. FormalParameterListHasInitializertrue이거나 FormalParameterHasInitializertrue이면 count를 반환한다.
  3. count + 1을 반환한다.
ArrowParameters : BindingIdentifier
  1. 1을 반환한다.
ArrowParameters : CoverParenthesizedExpressionAndArrowParameterList
  1. formalsArrowFormalParameters로 한다. 이는 coverCoverParenthesizedExpressionAndArrowParameterList에 의해 얻어진다.
  2. formalsExpectedArgumentCount를 반환한다.
PropertySetParameterList : FormalParameter
  1. FormalParameterHasInitializertrue이면 0을 반환한다.
  2. 1을 반환한다.
AsyncArrowBindingIdentifier : BindingIdentifier
  1. 1을 반환한다.

15.2 함수 정의

구문

FunctionDeclaration[Yield, Await, Default] : function BindingIdentifier[?Yield, ?Await] ( FormalParameters[~Yield, ~Await] ) { FunctionBody[~Yield, ~Await] } [+Default] function ( FormalParameters[~Yield, ~Await] ) { FunctionBody[~Yield, ~Await] } FunctionExpression : function BindingIdentifier[~Yield, ~Await]opt ( FormalParameters[~Yield, ~Await] ) { FunctionBody[~Yield, ~Await] } FunctionBody[Yield, Await] : FunctionStatementList[?Yield, ?Await] FunctionStatementList[Yield, Await] : StatementList[?Yield, ?Await, +Return]opt

15.2.1 정적 의미론: 초기 에러

FunctionDeclaration : function BindingIdentifier ( FormalParameters ) { FunctionBody } function ( FormalParameters ) { FunctionBody } FunctionExpression : function BindingIdentifieropt ( FormalParameters ) { FunctionBody } 참고

FunctionBodyLexicallyDeclaredNames에는 var 또는 function 선언을 통해 바인딩된 식별자가 포함되지 않는다.

FunctionBody : FunctionStatementList

15.2.2 정적 의미론: FunctionBodyContainsUseStrict

구문 지시 연산 FunctionBodyContainsUseStrict는 인수를 받지 않고 Boolean을 반환한다. 다음 생성식에 대해 조각별로 정의된다:

FunctionBody : FunctionStatementList
  1. FunctionBodyDirective PrologueUse Strict Directive가 포함되어 있으면 true를 반환하고, 그렇지 않으면 false를 반환한다.

15.2.3 런타임 의미론: EvaluateFunctionBody

구문 지시 연산 EvaluateFunctionBody는 인수 functionObject(ECMAScript 함수 객체)와 argumentsList(List of ECMAScript 언어 값)를 받고, return 완료(return completion) 또는 throw 완료(throw completion)를 반환한다. 다음 생성식에 대해 조각별로 정의된다:

FunctionBody : FunctionStatementList
  1. ? FunctionDeclarationInstantiation(functionObject, argumentsList)를 수행한다.
  2. ? Evaluation of FunctionStatementList를 수행한다.
  3. 참고: 이전 단계가 정상 완료(normal completion)를 반환했다면, FunctionStatementList의 끝까지 평가가 진행된 것이다.
  4. ReturnCompletion(undefined)를 반환한다.

15.2.4 런타임 의미론: InstantiateOrdinaryFunctionObject

구문 지시 연산 InstantiateOrdinaryFunctionObject는 인수 env(Environment Record)와 privateEnv(PrivateEnvironment Record 또는 null)를 받고, ECMAScript 함수 객체를 반환한다. 다음 생성식에 대해 조각별로 정의된다:

FunctionDeclaration : function BindingIdentifier ( FormalParameters ) { FunctionBody }
  1. nameBindingIdentifierStringValue로 한다.
  2. sourceText매치된 소스 텍스트(source text matched by) FunctionDeclaration로 한다.
  3. FOrdinaryFunctionCreate(%Function.prototype%, sourceText, FormalParameters, FunctionBody, non-lexical-this, env, privateEnv)로 한다.
  4. SetFunctionName(F, name)를 수행한다.
  5. MakeConstructor(F)를 수행한다.
  6. F를 반환한다.
FunctionDeclaration : function ( FormalParameters ) { FunctionBody }
  1. sourceText매치된 소스 텍스트(source text matched by) FunctionDeclaration로 한다.
  2. FOrdinaryFunctionCreate(%Function.prototype%, sourceText, FormalParameters, FunctionBody, non-lexical-this, env, privateEnv)로 한다.
  3. SetFunctionName(F, "default")를 수행한다.
  4. MakeConstructor(F)를 수행한다.
  5. F를 반환한다.
참고

익명 FunctionDeclarationexport default 선언의 일부로만 등장할 수 있으며, 그 함수 코드는 항상 엄격 모드 코드(strict mode code)이다.

15.2.5 런타임 의미론: InstantiateOrdinaryFunctionExpression

구문 지시 연산 InstantiateOrdinaryFunctionExpression은 선택적 인수 name(property key 또는 Private Name)를 받고, ECMAScript 함수 객체를 반환한다. 다음 생성식에 대해 조각별로 정의된다:

FunctionExpression : function ( FormalParameters ) { FunctionBody }
  1. name이 존재하지 않으면 name""로 설정한다.
  2. env실행 중인 실행 컨텍스트의 LexicalEnvironment로 한다.
  3. privateEnv실행 중인 실행 컨텍스트의 PrivateEnvironment로 한다.
  4. sourceText매치된 소스 텍스트(source text matched by) FunctionExpression로 한다.
  5. closureOrdinaryFunctionCreate(%Function.prototype%, sourceText, FormalParameters, FunctionBody, non-lexical-this, env, privateEnv)로 한다.
  6. SetFunctionName(closure, name)를 수행한다.
  7. MakeConstructor(closure)를 수행한다.
  8. closure를 반환한다.
FunctionExpression : function BindingIdentifier ( FormalParameters ) { FunctionBody }
  1. Assert: name이 존재하지 않는다.
  2. nameBindingIdentifierStringValue로 한다.
  3. outerEnv실행 중인 실행 컨텍스트의 LexicalEnvironment로 한다.
  4. funcEnvNewDeclarativeEnvironment(outerEnv)로 한다.
  5. ! funcEnv.CreateImmutableBinding(name, false)를 수행한다.
  6. privateEnv실행 중인 실행 컨텍스트의 PrivateEnvironment로 한다.
  7. sourceText매치된 소스 텍스트(source text matched by) FunctionExpression로 한다.
  8. closureOrdinaryFunctionCreate(%Function.prototype%, sourceText, FormalParameters, FunctionBody, non-lexical-this, funcEnv, privateEnv)로 한다.
  9. SetFunctionName(closure, name)를 수행한다.
  10. MakeConstructor(closure)를 수행한다.
  11. ! funcEnv.InitializeBinding(name, closure)를 수행한다.
  12. closure를 반환한다.
참고

BindingIdentifierFunctionExpression 내부에서 FunctionExpressionFunctionBody에서 참조될 수 있으므로 함수가 자기 자신을 재귀적으로 호출할 수 있다. 하지만 FunctionDeclaration과는 달리, BindingIdentifierFunctionExpression 바깥의 스코프에서 참조할 수 없으며, 해당 스코프에 영향을 미치지 않는다.

15.2.6 런타임 의미론: 평가

FunctionDeclaration : function BindingIdentifier ( FormalParameters ) { FunctionBody }
  1. empty를 반환한다.
참고 1

대안 의미론은 B.3.2에 제공되어 있다.

FunctionDeclaration : function ( FormalParameters ) { FunctionBody }
  1. empty를 반환한다.
FunctionExpression : function BindingIdentifieropt ( FormalParameters ) { FunctionBody }
  1. InstantiateOrdinaryFunctionExpression of FunctionExpression의 결과를 반환한다.
참고 2

FunctionDeclaration 또는 FunctionExpression을 사용하여 정의된 모든 함수에는 "prototype" 프로퍼티가 자동으로 생성되어, 해당 함수가 생성자(constructor)로 사용될 가능성을 허용한다.

FunctionStatementList : [비어 있음]
  1. undefined를 반환한다.

15.3 화살표 함수 정의

구문

ArrowFunction[In, Yield, Await] : ArrowParameters[?Yield, ?Await] [여기에 LineTerminator가 없음] => ConciseBody[?In] ArrowParameters[Yield, Await] : BindingIdentifier[?Yield, ?Await] CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await] ConciseBody[In] : [선행 기호 ≠ {] ExpressionBody[?In, ~Await] { FunctionBody[~Yield, ~Await] } ExpressionBody[In, Await] : AssignmentExpression[?In, ~Yield, ?Await]

보충 구문

다음 생성식의 인스턴스를 처리할 때
ArrowParameters[Yield, Await] : CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await]
CoverParenthesizedExpressionAndArrowParameterList의 해석은 아래의 문법을 사용하여 정제된다:

ArrowFormalParameters[Yield, Await] : ( UniqueFormalParameters[?Yield, ?Await] )

15.3.1 정적 의미론: 초기 에러

ArrowFunction : ArrowParameters => ConciseBody ArrowParameters : CoverParenthesizedExpressionAndArrowParameterList

15.3.2 정적 의미론: ConciseBodyContainsUseStrict

구문 지시 연산 ConciseBodyContainsUseStrict는 인수를 받지 않고 Boolean을 반환한다. 다음 생성식에 대해 조각별로 정의된다:

ConciseBody : ExpressionBody
  1. false를 반환한다.
ConciseBody : { FunctionBody }
  1. FunctionBodyContainsUseStrict of FunctionBody를 반환한다.

15.3.3 런타임 의미론: EvaluateConciseBody

구문 지시 연산 EvaluateConciseBody는 인수 functionObject(ECMAScript 함수 객체)와 argumentsList(List of ECMAScript 언어 값)를 받고, return 완료(return completion) 또는 throw 완료(throw completion)를 반환한다. 다음 생성식에 대해 조각별로 정의된다:

ConciseBody : ExpressionBody
  1. ? FunctionDeclarationInstantiation(functionObject, argumentsList)를 수행한다.
  2. ? Evaluation of ExpressionBody를 반환한다.

15.3.4 런타임 의미론: InstantiateArrowFunctionExpression

구문 지시 연산 InstantiateArrowFunctionExpression은 선택적 인수 name(property key 또는 Private Name)를 받고, ECMAScript 함수 객체를 반환한다. 다음 생성식에 대해 조각별로 정의된다:

ArrowFunction : ArrowParameters => ConciseBody
  1. name이 존재하지 않으면 name""로 설정한다.
  2. env실행 중인 실행 컨텍스트의 LexicalEnvironment로 한다.
  3. privateEnv실행 중인 실행 컨텍스트의 PrivateEnvironment로 한다.
  4. sourceText매치된 소스 텍스트(source text matched by) ArrowFunction로 한다.
  5. closureOrdinaryFunctionCreate(%Function.prototype%, sourceText, ArrowParameters, ConciseBody, lexical-this, env, privateEnv)로 한다.
  6. SetFunctionName(closure, name)를 수행한다.
  7. closure를 반환한다.
참고

ArrowFunctionarguments, super, this, new.target에 대한 지역 바인딩을 정의하지 않는다. ArrowFunction 내에서 arguments, super, this, new.target에 대한 참조는 반드시 렉시컬 상위 환경의 바인딩을 참조해야 한다. 일반적으로 이는 바로 상위 함수의 Function Environment가 된다. ArrowFunctionsuper를 포함하더라도, 함수 객체5단계에서 MakeMethod를 통해 메서드로 만들어지지 않는다. ArrowFunctionsuper를 참조하는 경우, 반드시 비-ArrowFunction 내에 포함되어 있고, 함수 객체가 캡처한 env를 통해 super를 구현하는 데 필요한 상태를 접근할 수 있다.

15.3.5 런타임 의미론: 평가

ArrowFunction : ArrowParameters => ConciseBody
  1. InstantiateArrowFunctionExpression of ArrowFunction의 결과를 반환한다.
ExpressionBody : AssignmentExpression
  1. exprRef를 ? Evaluation of AssignmentExpression의 결과로 한다.
  2. exprValue를 ? GetValue(exprRef)의 결과로 한다.
  3. ReturnCompletion(exprValue)를 반환한다.

15.4 메서드 정의

구문

MethodDefinition[Yield, Await] : ClassElementName[?Yield, ?Await] ( UniqueFormalParameters[~Yield, ~Await] ) { FunctionBody[~Yield, ~Await] } GeneratorMethod[?Yield, ?Await] AsyncMethod[?Yield, ?Await] AsyncGeneratorMethod[?Yield, ?Await] get ClassElementName[?Yield, ?Await] ( ) { FunctionBody[~Yield, ~Await] } set ClassElementName[?Yield, ?Await] ( PropertySetParameterList ) { FunctionBody[~Yield, ~Await] } PropertySetParameterList : FormalParameter[~Yield, ~Await]

15.4.1 정적 의미론: 초기 에러

MethodDefinition : ClassElementName ( UniqueFormalParameters ) { FunctionBody } MethodDefinition : set ClassElementName ( PropertySetParameterList ) { FunctionBody }

15.4.2 정적 의미론: HasDirectSuper

구문 지시 연산 HasDirectSuper는 인수를 받지 않고 Boolean을 반환한다. 다음 생성식에 대해 조각별로 정의된다:

MethodDefinition : ClassElementName ( UniqueFormalParameters ) { FunctionBody }
  1. UniqueFormalParameters Contains SuperCalltrue이면 true를 반환한다.
  2. FunctionBody Contains SuperCall의 결과를 반환한다.
MethodDefinition : get ClassElementName ( ) { FunctionBody }
  1. FunctionBody Contains SuperCall의 결과를 반환한다.
MethodDefinition : set ClassElementName ( PropertySetParameterList ) { FunctionBody }
  1. PropertySetParameterList Contains SuperCalltrue이면 true를 반환한다.
  2. FunctionBody Contains SuperCall의 결과를 반환한다.
GeneratorMethod : * ClassElementName ( UniqueFormalParameters ) { GeneratorBody }
  1. UniqueFormalParameters Contains SuperCalltrue이면 true를 반환한다.
  2. GeneratorBody Contains SuperCall의 결과를 반환한다.
AsyncGeneratorMethod : async * ClassElementName ( UniqueFormalParameters ) { AsyncGeneratorBody }
  1. UniqueFormalParameters Contains SuperCalltrue이면 true를 반환한다.
  2. AsyncGeneratorBody Contains SuperCall의 결과를 반환한다.
AsyncMethod : async ClassElementName ( UniqueFormalParameters ) { AsyncFunctionBody }
  1. UniqueFormalParameters Contains SuperCalltrue이면 true를 반환한다.
  2. AsyncFunctionBody Contains SuperCall의 결과를 반환한다.

15.4.3 정적 의미론: SpecialMethod

구문 지시 연산 SpecialMethod는 인수를 받지 않고 Boolean을 반환한다. 다음 생성식에 대해 조각별로 정의된다:

MethodDefinition : ClassElementName ( UniqueFormalParameters ) { FunctionBody }
  1. false를 반환한다.
MethodDefinition : GeneratorMethod AsyncMethod AsyncGeneratorMethod get ClassElementName ( ) { FunctionBody } set ClassElementName ( PropertySetParameterList ) { FunctionBody }
  1. true를 반환한다.

15.4.4 런타임 의미론: DefineMethod

구문 지시 연산 DefineMethod는 인수 object(Object)와 선택적 인수 functionPrototype(Object)를 받고, 정상 완료(normal completion)(Record, 필드 [[Key]](property key)와 [[Closure]](ECMAScript 함수 객체)) 또는 비정상 완료(abrupt completion)를 반환한다. 다음 생성식에 대해 조각별로 정의된다:

MethodDefinition : ClassElementName ( UniqueFormalParameters ) { FunctionBody }
  1. propKey를 ? Evaluation of ClassElementName의 결과로 한다.
  2. env실행 중인 실행 컨텍스트의 LexicalEnvironment로 한다.
  3. privateEnv실행 중인 실행 컨텍스트의 PrivateEnvironment로 한다.
  4. functionPrototype이 존재하면,
    1. prototypefunctionPrototype으로 한다.
  5. 그 외에는,
    1. prototype%Function.prototype%로 한다.
  6. sourceText매치된 소스 텍스트(source text matched by) MethodDefinition로 한다.
  7. closureOrdinaryFunctionCreate(prototype, sourceText, UniqueFormalParameters, FunctionBody, non-lexical-this, env, privateEnv)로 한다.
  8. MakeMethod(closure, object)를 수행한다.
  9. Record { [[Key]]: propKey, [[Closure]]: closure }를 반환한다.

15.4.5 런타임 의미론: MethodDefinitionEvaluation

구문 지시 연산 MethodDefinitionEvaluation은 인수 object(Object)와 enumerable(Boolean)을 받고, 정상 완료(PrivateElement 또는 unused), 또는 비정상 완료를 반환한다. 다음 생성식에 대해 조각별로 정의된다:

MethodDefinition : ClassElementName ( UniqueFormalParameters ) { FunctionBody }
  1. methodDef를 ? DefineMethod of MethodDefinitionobject 인수를 넘겨서 수행한 결과로 한다.
  2. SetFunctionName(methodDef.[[Closure]], methodDef.[[Key]])를 수행한다.
  3. ? DefineMethodProperty(object, methodDef.[[Key]], methodDef.[[Closure]], enumerable)를 반환한다.
MethodDefinition : get ClassElementName ( ) { FunctionBody }
  1. propKey를 ? Evaluation of ClassElementName의 결과로 한다.
  2. env실행 중인 실행 컨텍스트의 LexicalEnvironment로 한다.
  3. privateEnv실행 중인 실행 컨텍스트의 PrivateEnvironment로 한다.
  4. sourceText매치된 소스 텍스트(source text matched by) MethodDefinition로 한다.
  5. formalParameterList를 아래 생성식의 인스턴스로 한다: FormalParameters : [비어 있음] .
  6. closureOrdinaryFunctionCreate(%Function.prototype%, sourceText, formalParameterList, FunctionBody, non-lexical-this, env, privateEnv)로 한다.
  7. MakeMethod(closure, object)를 수행한다.
  8. SetFunctionName(closure, propKey, "get")를 수행한다.
  9. propKeyPrivate Name이면,
    1. PrivateElement { [[Key]]: propKey, [[Kind]]: accessor, [[Get]]: closure, [[Set]]: undefined }를 반환한다.
  10. 그 외에는,
    1. desc를 PropertyDescriptor { [[Get]]: closure, [[Enumerable]]: enumerable, [[Configurable]]: true }로 한다.
    2. ? DefinePropertyOrThrow(object, propKey, desc)를 수행한다.
    3. unused를 반환한다.
MethodDefinition : set ClassElementName ( PropertySetParameterList ) { FunctionBody }
  1. propKey를 ? Evaluation of ClassElementName의 결과로 한다.
  2. env실행 중인 실행 컨텍스트의 LexicalEnvironment로 한다.
  3. privateEnv실행 중인 실행 컨텍스트의 PrivateEnvironment로 한다.
  4. sourceText매치된 소스 텍스트(source text matched by) MethodDefinition로 한다.
  5. closureOrdinaryFunctionCreate(%Function.prototype%, sourceText, PropertySetParameterList, FunctionBody, non-lexical-this, env, privateEnv)로 한다.
  6. MakeMethod(closure, object)를 수행한다.
  7. SetFunctionName(closure, propKey, "set")를 수행한다.
  8. propKeyPrivate Name이면,
    1. PrivateElement { [[Key]]: propKey, [[Kind]]: accessor, [[Get]]: undefined, [[Set]]: closure }를 반환한다.
  9. 그 외에는,
    1. desc를 PropertyDescriptor { [[Set]]: closure, [[Enumerable]]: enumerable, [[Configurable]]: true }로 한다.
    2. ? DefinePropertyOrThrow(object, propKey, desc)를 수행한다.
    3. unused를 반환한다.
GeneratorMethod : * ClassElementName ( UniqueFormalParameters ) { GeneratorBody }
  1. propKey를 ? Evaluation of ClassElementName의 결과로 한다.
  2. env실행 중인 실행 컨텍스트의 LexicalEnvironment로 한다.
  3. privateEnv실행 중인 실행 컨텍스트의 PrivateEnvironment로 한다.
  4. sourceText매치된 소스 텍스트(source text matched by) GeneratorMethod로 한다.
  5. closureOrdinaryFunctionCreate(%GeneratorFunction.prototype%, sourceText, UniqueFormalParameters, GeneratorBody, non-lexical-this, env, privateEnv)로 한다.
  6. MakeMethod(closure, object)를 수행한다.
  7. SetFunctionName(closure, propKey)를 수행한다.
  8. prototypeOrdinaryObjectCreate(%GeneratorPrototype%)로 한다.
  9. ! DefinePropertyOrThrow(closure, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false })를 수행한다.
  10. ? DefineMethodProperty(object, propKey, closure, enumerable)를 반환한다.
AsyncGeneratorMethod : async * ClassElementName ( UniqueFormalParameters ) { AsyncGeneratorBody }
  1. propKey를 ? Evaluation of ClassElementName의 결과로 한다.
  2. env실행 중인 실행 컨텍스트의 LexicalEnvironment로 한다.
  3. privateEnv실행 중인 실행 컨텍스트의 PrivateEnvironment로 한다.
  4. sourceText매치된 소스 텍스트(source text matched by) AsyncGeneratorMethod로 한다.
  5. closureOrdinaryFunctionCreate(%AsyncGeneratorFunction.prototype%, sourceText, UniqueFormalParameters, AsyncGeneratorBody, non-lexical-this, env, privateEnv)로 한다.
  6. MakeMethod(closure, object)를 수행한다.
  7. SetFunctionName(closure, propKey)를 수행한다.
  8. prototypeOrdinaryObjectCreate(%AsyncGeneratorPrototype%)로 한다.
  9. ! DefinePropertyOrThrow(closure, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false })를 수행한다.
  10. ? DefineMethodProperty(object, propKey, closure, enumerable)를 반환한다.
AsyncMethod : async ClassElementName ( UniqueFormalParameters ) { AsyncFunctionBody }
  1. propKey를 ? Evaluation of ClassElementName의 결과로 한다.
  2. env실행 중인 실행 컨텍스트의 LexicalEnvironment로 한다.
  3. privateEnv실행 중인 실행 컨텍스트의 PrivateEnvironment로 한다.
  4. sourceText매치된 소스 텍스트(source text matched by) AsyncMethod로 한다.
  5. closureOrdinaryFunctionCreate(%AsyncFunction.prototype%, sourceText, UniqueFormalParameters, AsyncFunctionBody, non-lexical-this, env, privateEnv)로 한다.
  6. MakeMethod(closure, object)를 수행한다.
  7. SetFunctionName(closure, propKey)를 수행한다.
  8. DefineMethodProperty(object, propKey, closure, enumerable)를 반환한다.

15.5 제너레이터 함수 정의

구문

GeneratorDeclaration[Yield, Await, Default] : function * BindingIdentifier[?Yield, ?Await] ( FormalParameters[+Yield, ~Await] ) { GeneratorBody } [+Default] function * ( FormalParameters[+Yield, ~Await] ) { GeneratorBody } GeneratorExpression : function * BindingIdentifier[+Yield, ~Await]opt ( FormalParameters[+Yield, ~Await] ) { GeneratorBody } GeneratorMethod[Yield, Await] : * ClassElementName[?Yield, ?Await] ( UniqueFormalParameters[+Yield, ~Await] ) { GeneratorBody } GeneratorBody : FunctionBody[+Yield, ~Await] YieldExpression[In, Await] : yield yield [여기에 LineTerminator가 없음] AssignmentExpression[?In, +Yield, ?Await] yield [여기에 LineTerminator가 없음] * AssignmentExpression[?In, +Yield, ?Await] 참고 1

yield 바로 뒤의 구문 맥락에서는 InputElementRegExpOrTemplateTail 렉시컬 목표(lexical goal)를 사용해야 한다.

참고 2

YieldExpression은 제너레이터 함수의 FormalParameters 내에서는 사용할 수 없다. 왜냐하면 FormalParameters에 포함된 모든 표현식은 Generator가 재개(resumable) 상태가 되기 전에 평가되기 때문이다.

참고 3

제너레이터와 관련된 추상 연산(abstract operations)27.5.3에 정의되어 있다.

15.5.1 정적 의미론: 초기 에러

GeneratorMethod : * ClassElementName ( UniqueFormalParameters ) { GeneratorBody } GeneratorDeclaration : function * BindingIdentifier ( FormalParameters ) { GeneratorBody } function * ( FormalParameters ) { GeneratorBody } GeneratorExpression : function * BindingIdentifieropt ( FormalParameters ) { GeneratorBody }

15.5.2 런타임 의미론: EvaluateGeneratorBody

구문 지시 연산 EvaluateGeneratorBody는 인수 functionObject(ECMAScript 함수 객체)와 argumentsList(List of ECMAScript 언어 값)를 받고, throw 완료(throw completion) 또는 return 완료(return completion)를 반환한다. 다음 생성식에 대해 조각별로 정의된다:

GeneratorBody : FunctionBody
  1. ? FunctionDeclarationInstantiation(functionObject, argumentsList)를 수행한다.
  2. G를 ? OrdinaryCreateFromConstructor(functionObject, "%GeneratorPrototype%", « [[GeneratorState]], [[GeneratorContext]], [[GeneratorBrand]] »)의 결과로 한다.
  3. G.[[GeneratorBrand]]empty로 설정한다.
  4. G.[[GeneratorState]]suspended-start로 설정한다.
  5. GeneratorStart(G, FunctionBody)를 수행한다.
  6. ReturnCompletion(G)를 반환한다.

15.5.3 런타임 의미론: InstantiateGeneratorFunctionObject

구문 지시 연산 InstantiateGeneratorFunctionObject는 인수 env(Environment Record)와 privateEnv(PrivateEnvironment Record 또는 null)를 받고, ECMAScript 함수 객체를 반환한다. 다음 생성식에 대해 조각별로 정의된다:

GeneratorDeclaration : function * BindingIdentifier ( FormalParameters ) { GeneratorBody }
  1. nameBindingIdentifierStringValue로 한다.
  2. sourceText매치된 소스 텍스트(source text matched by) GeneratorDeclaration로 한다.
  3. FOrdinaryFunctionCreate(%GeneratorFunction.prototype%, sourceText, FormalParameters, GeneratorBody, non-lexical-this, env, privateEnv)로 한다.
  4. SetFunctionName(F, name)를 수행한다.
  5. prototypeOrdinaryObjectCreate(%GeneratorPrototype%)로 한다.
  6. ! DefinePropertyOrThrow(F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false })를 수행한다.
  7. F를 반환한다.
GeneratorDeclaration : function * ( FormalParameters ) { GeneratorBody }
  1. sourceTextGeneratorDeclaration에 의해 매치된 소스 텍스트(source text matched by)로 한다.
  2. FOrdinaryFunctionCreate(%GeneratorFunction.prototype%, sourceText, FormalParameters, GeneratorBody, non-lexical-this, env, privateEnv)로 한다.
  3. SetFunctionName(F, "default")를 수행한다.
  4. prototypeOrdinaryObjectCreate(%GeneratorPrototype%)로 한다.
  5. ! DefinePropertyOrThrow(F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false })를 수행한다.
  6. F를 반환한다.
참고

익명 GeneratorDeclarationexport default 선언의 일부로만 등장할 수 있으며, 해당 함수 코드는 항상 엄격 모드 코드(strict mode code)이다.

15.5.4 런타임 의미론: InstantiateGeneratorFunctionExpression

구문 지시 연산 InstantiateGeneratorFunctionExpression은 선택적 인수 name(property key 또는 Private Name)를 받고 ECMAScript 함수 객체를 반환한다. 다음 생성식에 대해 조각별로 정의된다:

GeneratorExpression : function * ( FormalParameters ) { GeneratorBody }
  1. name이 존재하지 않으면 name""로 설정한다.
  2. env실행 중인 실행 컨텍스트의 LexicalEnvironment로 한다.
  3. privateEnv실행 중인 실행 컨텍스트의 PrivateEnvironment로 한다.
  4. sourceText매치된 소스 텍스트(source text matched by) GeneratorExpression로 한다.
  5. closureOrdinaryFunctionCreate(%GeneratorFunction.prototype%, sourceText, FormalParameters, GeneratorBody, non-lexical-this, env, privateEnv)로 한다.
  6. SetFunctionName(closure, name)를 수행한다.
  7. prototypeOrdinaryObjectCreate(%GeneratorPrototype%)로 한다.
  8. ! DefinePropertyOrThrow(closure, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false })를 수행한다.
  9. closure를 반환한다.
GeneratorExpression : function * BindingIdentifier ( FormalParameters ) { GeneratorBody }
  1. Assert: name이 존재하지 않는다.
  2. nameBindingIdentifierStringValue로 한다.
  3. outerEnv실행 중인 실행 컨텍스트의 LexicalEnvironment로 한다.
  4. funcEnvNewDeclarativeEnvironment(outerEnv)로 한다.
  5. ! funcEnv.CreateImmutableBinding(name, false)를 수행한다.
  6. privateEnv실행 중인 실행 컨텍스트의 PrivateEnvironment로 한다.
  7. sourceText매치된 소스 텍스트(source text matched by) GeneratorExpression로 한다.
  8. closureOrdinaryFunctionCreate(%GeneratorFunction.prototype%, sourceText, FormalParameters, GeneratorBody, non-lexical-this, funcEnv, privateEnv)로 한다.
  9. SetFunctionName(closure, name)를 수행한다.
  10. prototypeOrdinaryObjectCreate(%GeneratorPrototype%)로 한다.
  11. ! DefinePropertyOrThrow(closure, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false })를 수행한다.
  12. ! funcEnv.InitializeBinding(name, closure)를 수행한다.
  13. closure를 반환한다.
참고

BindingIdentifierGeneratorExpression 내부에서 GeneratorExpressionFunctionBody에서 참조될 수 있으므로, 제너레이터 코드가 자기 자신을 재귀적으로 호출할 수 있다. 하지만 GeneratorDeclaration과는 달리, BindingIdentifierGeneratorExpression 바깥의 스코프에서 참조할 수 없으며, 해당 스코프에 영향을 미치지 않는다.

15.5.5 런타임 의미론: 평가

GeneratorExpression : function * BindingIdentifieropt ( FormalParameters ) { GeneratorBody }
  1. InstantiateGeneratorFunctionExpression of GeneratorExpression의 결과를 반환한다.
YieldExpression : yield
  1. ? Yield(undefined)를 반환한다.
YieldExpression : yield AssignmentExpression
  1. exprRef를 ? Evaluation of AssignmentExpression의 결과로 한다.
  2. value를 ? GetValue(exprRef)의 결과로 한다.
  3. ? Yield(value)를 반환한다.
YieldExpression : yield * AssignmentExpression
  1. generatorKindGetGeneratorKind()의 결과로 한다.
  2. Assert: generatorKindsync 또는 async이다.
  3. exprRef를 ? Evaluation of AssignmentExpression의 결과로 한다.
  4. value를 ? GetValue(exprRef)의 결과로 한다.
  5. iteratorRecord를 ? GetIterator(value, generatorKind)의 결과로 한다.
  6. iteratoriteratorRecord.[[Iterator]]로 한다.
  7. receivedNormalCompletion(undefined)로 한다.
  8. 반복한다,
    1. received정상 완료(normal completion)이면,
      1. innerResult를 ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]], « received.[[Value]] »)의 결과로 한다.
      2. generatorKindasync이면, innerResult를 ? Await(innerResult)의 결과로 설정한다.
      3. innerResult객체가 아니면, TypeError 예외를 던진다.
      4. done를 ? IteratorComplete(innerResult)의 결과로 한다.
      5. donetrue이면,
        1. ? IteratorValue(innerResult)를 반환한다.
      6. generatorKindasync이면, receivedCompletion(AsyncGeneratorYield(? IteratorValue(innerResult)))로 설정한다.
      7. 그 외에는, receivedCompletion(GeneratorYield(innerResult))로 설정한다.
    2. 그 외에 receivedthrow 완료(throw completion)이면,
      1. throw를 ? GetMethod(iterator, "throw")의 결과로 한다.
      2. throwundefined가 아니면,
        1. innerResult를 ? Call(throw, iterator, « received.[[Value]] »)의 결과로 한다.
        2. generatorKindasync이면, innerResult를 ? Await(innerResult)의 결과로 설정한다.
        3. 참고: 내부 iterator throw 메서드의 예외는 전파된다. 내부 throw 메서드의 정상 완료(normal completion)는 내부 next와 유사하게 처리된다.
        4. innerResult객체가 아니면, TypeError 예외를 던진다.
        5. done를 ? IteratorComplete(innerResult)의 결과로 한다.
        6. donetrue이면,
          1. ? IteratorValue(innerResult)를 반환한다.
        7. generatorKindasync이면, receivedCompletion(AsyncGeneratorYield(? IteratorValue(innerResult)))로 설정한다.
        8. 그 외에는, receivedCompletion(GeneratorYield(innerResult))로 설정한다.
      3. 그 외에는,
        1. 참고: iteratorthrow 메서드가 없으면, 이 throw는 yield* 루프를 종료한다. 단, 먼저 iterator에 정리(clean up) 기회를 준다.
        2. closeCompletionNormalCompletion(empty)로 한다.
        3. generatorKindasync이면, ? AsyncIteratorClose(iteratorRecord, closeCompletion)를 수행한다.
        4. 그 외에는, ? IteratorClose(iteratorRecord, closeCompletion)를 수행한다.
        5. 참고: 다음 단계는 yield* 프로토콜 위반을 나타내기 위해 TypeError를 던진다: iteratorthrow 메서드가 없다.
        6. TypeError 예외를 던진다.
    3. 그 외에는,
      1. Assert: receivedreturn 완료(return completion)이다.
      2. return을 ? GetMethod(iterator, "return")의 결과로 한다.
      3. returnundefined이면,
        1. valuereceived.[[Value]]로 설정한다.
        2. generatorKindasync이면,
          1. value를 ? Await(value)의 결과로 설정한다.
        3. ReturnCompletion(value)를 반환한다.
      4. innerReturnResult를 ? Call(return, iterator, « received.[[Value]] »)의 결과로 한다.
      5. generatorKindasync이면, innerReturnResult를 ? Await(innerReturnResult)의 결과로 설정한다.
      6. innerReturnResult객체가 아니면, TypeError 예외를 던진다.
      7. done를 ? IteratorComplete(innerReturnResult)의 결과로 한다.
      8. donetrue이면,
        1. value를 ? IteratorValue(innerReturnResult)의 결과로 설정한다.
        2. ReturnCompletion(value)를 반환한다.
      9. generatorKindasync이면, receivedCompletion(AsyncGeneratorYield(? IteratorValue(innerReturnResult)))로 설정한다.
      10. 그 외에는, receivedCompletion(GeneratorYield(innerReturnResult))로 설정한다.

15.6 비동기 제너레이터 함수 정의

구문

AsyncGeneratorDeclaration[Yield, Await, Default] : async [여기에는 LineTerminator 없음] function * BindingIdentifier[?Yield, ?Await] ( FormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } [+Default] async [여기에는 LineTerminator 없음] function * ( FormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } AsyncGeneratorExpression : async [여기에는 LineTerminator 없음] function * BindingIdentifier[+Yield, +Await]opt ( FormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } AsyncGeneratorMethod[Yield, Await] : async [여기에는 LineTerminator 없음] * ClassElementName[?Yield, ?Await] ( UniqueFormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } AsyncGeneratorBody : FunctionBody[+Yield, +Await] 참고 1

YieldExpressionAwaitExpression은 비동기 제너레이터 함수의 FormalParameters 내에서 사용할 수 없습니다. 왜냐하면 FormalParameters의 일부인 모든 식은 생성된 AsyncGenerator가 재개 가능한 상태가 되기 전에 평가되기 때문입니다.

참고 2

AsyncGenerator와 관련된 추상 연산들은 27.6.3에 정의되어 있습니다.

15.6.1 정적 의미론: 초기 오류

AsyncGeneratorMethod : async * ClassElementName ( UniqueFormalParameters ) { AsyncGeneratorBody } AsyncGeneratorDeclaration : async function * BindingIdentifier ( FormalParameters ) { AsyncGeneratorBody } async function * ( FormalParameters ) { AsyncGeneratorBody } AsyncGeneratorExpression : async function * BindingIdentifieropt ( FormalParameters ) { AsyncGeneratorBody }

15.6.2 실행 시 의미론: EvaluateAsyncGeneratorBody

구문 지향 연산 EvaluateAsyncGeneratorBody는 functionObject(ECMAScript 함수 객체)와 argumentsList(List 타입의 ECMAScript 언어 값 목록) 인자를 받고, throw completion 또는 return completion을 반환합니다. 다음 생성식에 대해 개별적으로 정의됩니다:

AsyncGeneratorBody : FunctionBody
  1. FunctionDeclarationInstantiation(functionObject, argumentsList)를 수행한다.
  2. generator를 ? OrdinaryCreateFromConstructor(functionObject, "%AsyncGeneratorPrototype%", « [[AsyncGeneratorState]], [[AsyncGeneratorContext]], [[AsyncGeneratorQueue]], [[GeneratorBrand]] »)로 한다.
  3. generator.[[GeneratorBrand]]empty로 설정한다.
  4. generator.[[AsyncGeneratorState]]suspended-start로 설정한다.
  5. AsyncGeneratorStart(generator, FunctionBody)를 수행한다.
  6. ReturnCompletion(generator)를 반환한다.

15.6.3 실행 시 의미론: InstantiateAsyncGeneratorFunctionObject

구문 지향 연산 InstantiateAsyncGeneratorFunctionObject는 env(Environment Record 타입)와 privateEnv(PrivateEnvironment Record 또는 null) 인자를 받고, ECMAScript 함수 객체를 반환합니다. 다음 생성식에 대해 개별적으로 정의됩니다:

AsyncGeneratorDeclaration : async function * BindingIdentifier ( FormalParameters ) { AsyncGeneratorBody }
  1. nameStringValue of BindingIdentifier로 한다.
  2. sourceTextAsyncGeneratorDeclaration에 매치된 소스 텍스트로 한다.
  3. FOrdinaryFunctionCreate(%AsyncGeneratorFunction.prototype%, sourceText, FormalParameters, AsyncGeneratorBody, non-lexical-this, env, privateEnv)로 한다.
  4. SetFunctionName(F, name)을 수행한다.
  5. prototypeOrdinaryObjectCreate(%AsyncGeneratorPrototype%)로 한다.
  6. DefinePropertyOrThrow(F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false })를 수행한다.
  7. F를 반환한다.
AsyncGeneratorDeclaration : async function * ( FormalParameters ) { AsyncGeneratorBody }
  1. sourceTextAsyncGeneratorDeclaration에 매치된 소스 텍스트로 한다.
  2. FOrdinaryFunctionCreate(%AsyncGeneratorFunction.prototype%, sourceText, FormalParameters, AsyncGeneratorBody, non-lexical-this, env, privateEnv)로 한다.
  3. SetFunctionName(F, "default")를 수행한다.
  4. prototypeOrdinaryObjectCreate(%AsyncGeneratorPrototype%)로 한다.
  5. DefinePropertyOrThrow(F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false })를 수행한다.
  6. F를 반환한다.
참고

익명 AsyncGeneratorDeclarationexport default 선언의 일부로만 나타날 수 있습니다.

15.6.4 실행 시 의미론: InstantiateAsyncGeneratorFunctionExpression

구문 지향 연산 InstantiateAsyncGeneratorFunctionExpression은 선택적 인자 name(프로퍼티 키 또는 Private Name)를 받고, ECMAScript 함수 객체를 반환합니다. 다음 생성식에 대해 개별적으로 정의됩니다:

AsyncGeneratorExpression : async function * ( FormalParameters ) { AsyncGeneratorBody }
  1. name이 존재하지 않으면 name""로 설정한다.
  2. env실행 중인 실행 컨텍스트의 LexicalEnvironment로 한다.
  3. privateEnv실행 중인 실행 컨텍스트의 PrivateEnvironment로 한다.
  4. sourceTextAsyncGeneratorExpression에 매치된 소스 텍스트로 한다.
  5. closureOrdinaryFunctionCreate(%AsyncGeneratorFunction.prototype%, sourceText, FormalParameters, AsyncGeneratorBody, non-lexical-this, env, privateEnv)로 한다.
  6. SetFunctionName(closure, name)을 수행한다.
  7. prototypeOrdinaryObjectCreate(%AsyncGeneratorPrototype%)로 한다.
  8. DefinePropertyOrThrow(closure, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false })를 수행한다.
  9. closure를 반환한다.
AsyncGeneratorExpression : async function * BindingIdentifier ( FormalParameters ) { AsyncGeneratorBody }
  1. Assert: name이 존재하지 않는다.
  2. nameStringValue of BindingIdentifier로 설정한다.
  3. outerEnv실행 중인 실행 컨텍스트의 LexicalEnvironment로 한다.
  4. funcEnvNewDeclarativeEnvironment(outerEnv)로 한다.
  5. funcEnv.CreateImmutableBinding(name, false)을 수행한다.
  6. privateEnv실행 중인 실행 컨텍스트의 PrivateEnvironment로 한다.
  7. sourceTextAsyncGeneratorExpression에 매치된 소스 텍스트로 한다.
  8. closureOrdinaryFunctionCreate(%AsyncGeneratorFunction.prototype%, sourceText, FormalParameters, AsyncGeneratorBody, non-lexical-this, funcEnv, privateEnv)로 한다.
  9. SetFunctionName(closure, name)을 수행한다.
  10. prototypeOrdinaryObjectCreate(%AsyncGeneratorPrototype%)로 한다.
  11. DefinePropertyOrThrow(closure, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false })를 수행한다.
  12. funcEnv.InitializeBinding(name, closure)을 수행한다.
  13. closure를 반환한다.
참고

BindingIdentifierAsyncGeneratorExpression에 포함되어 있을 경우, AsyncGeneratorExpressionAsyncGeneratorBody 내부에서 참조할 수 있으므로 제너레이터 코드가 자기 자신을 재귀적으로 호출할 수 있습니다. 그러나 AsyncGeneratorDeclaration의 경우와는 달리, BindingIdentifierAsyncGeneratorExpression에 포함되어 있을 경우, AsyncGeneratorExpression을 둘러싼 스코프에서 참조할 수 없으며, 그 스코프에 영향을 주지 않습니다.

15.6.5 실행 시 의미론: Evaluation

AsyncGeneratorExpression : async function * BindingIdentifieropt ( FormalParameters ) { AsyncGeneratorBody }
  1. InstantiateAsyncGeneratorFunctionExpression of AsyncGeneratorExpression을 반환한다.

15.7 클래스 정의

구문

ClassDeclaration[Yield, Await, Default] : class BindingIdentifier[?Yield, ?Await] ClassTail[?Yield, ?Await] [+Default] class ClassTail[?Yield, ?Await] ClassExpression[Yield, Await] : class BindingIdentifier[?Yield, ?Await]opt ClassTail[?Yield, ?Await] ClassTail[Yield, Await] : ClassHeritage[?Yield, ?Await]opt { ClassBody[?Yield, ?Await]opt } ClassHeritage[Yield, Await] : extends LeftHandSideExpression[?Yield, ?Await] ClassBody[Yield, Await] : ClassElementList[?Yield, ?Await] ClassElementList[Yield, Await] : ClassElement[?Yield, ?Await] ClassElementList[?Yield, ?Await] ClassElement[?Yield, ?Await] ClassElement[Yield, Await] : MethodDefinition[?Yield, ?Await] static MethodDefinition[?Yield, ?Await] FieldDefinition[?Yield, ?Await] ; static FieldDefinition[?Yield, ?Await] ; ClassStaticBlock ; FieldDefinition[Yield, Await] : ClassElementName[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt ClassElementName[Yield, Await] : PropertyName[?Yield, ?Await] PrivateIdentifier ClassStaticBlock : static { ClassStaticBlockBody } ClassStaticBlockBody : ClassStaticBlockStatementList ClassStaticBlockStatementList : StatementList[~Yield, +Await, ~Return]opt 참고

클래스 정의는 항상 strict mode code입니다.

15.7.1 정적 의미론: 초기 오류

ClassTail : ClassHeritageopt { ClassBody }
  • 다음 알고리즘이 true를 반환하고 ClassHeritage가 존재하지 않는 경우, 문법 오류입니다:

    1. constructorConstructorMethod of ClassBody로 한다.
    2. constructorempty라면, false를 반환한다.
    3. constructorHasDirectSuper를 반환한다.
ClassBody : ClassElementList
  • PrototypePropertyNameList of ClassElementList"constructor"가 둘 이상 포함된 경우 문법 오류입니다.
  • PrivateBoundIdentifiers of ClassElementList에 중복된 항목이 존재하는 경우(단, 이름이 게터와 세터에 각각 한 번씩만 사용되고, 그 외에는 사용되지 않으며, 게터와 세터가 모두 static이거나 모두 static이 아니면 예외), 문법 오류입니다.
ClassElement : MethodDefinition ClassElement : static MethodDefinition ClassElement : FieldDefinition ; ClassElement : static FieldDefinition ; FieldDefinition : ClassElementName Initializeropt ClassElementName : PrivateIdentifier ClassStaticBlockBody : ClassStaticBlockStatementList

15.7.2 정적 의미론: ClassElementKind

구문 지향 연산 ClassElementKind는 인자를 받지 않으며, constructor-method, non-constructor-method, 또는 empty를 반환합니다. 다음 생성식에 대해 개별적으로 정의됩니다:

ClassElement : MethodDefinition
  1. MethodDefinitionPropName"constructor"이면, constructor-method를 반환한다.
  2. non-constructor-method를 반환한다.
ClassElement : static MethodDefinition FieldDefinition ; static FieldDefinition ;
  1. non-constructor-method를 반환한다.
ClassElement : ClassStaticBlock
  1. non-constructor-method를 반환한다.
ClassElement : ;
  1. empty를 반환한다.

15.7.3 정적 의미론: ConstructorMethod

구문 지향 연산 ConstructorMethod는 인자를 받지 않으며, ClassElement 파싱 노드 또는 empty를 반환합니다. 다음 생성식에 대해 개별적으로 정의됩니다:

ClassElementList : ClassElement
  1. ClassElementClassElementKindconstructor-method이면, ClassElement를 반환한다.
  2. empty를 반환한다.
ClassElementList : ClassElementList ClassElement
  1. headConstructorMethod of ClassElementList로 한다.
  2. headempty가 아니면 head를 반환한다.
  3. ClassElementClassElementKindconstructor-method이면, ClassElement를 반환한다.
  4. empty를 반환한다.
참고

초기 오류 규칙은 "constructor"라는 이름의 메서드 정의가 하나만 존재하며, 접근자 프로퍼티 또는 제너레이터 정의가 아님을 보장합니다.

15.7.4 정적 의미론: IsStatic

구문 지향 연산 IsStatic은 인자를 받지 않으며, Boolean을 반환합니다. 다음 생성식에 대해 개별적으로 정의됩니다:

ClassElement : MethodDefinition
  1. false를 반환한다.
ClassElement : static MethodDefinition
  1. true를 반환한다.
ClassElement : FieldDefinition ;
  1. false를 반환한다.
ClassElement : static FieldDefinition ;
  1. true를 반환한다.
ClassElement : ClassStaticBlock
  1. true를 반환한다.
ClassElement : ;
  1. false를 반환한다.

15.7.5 정적 의미론: NonConstructorElements

구문 지향 연산 NonConstructorElements는 인자를 받지 않으며, List 타입의 ClassElement 파싱 노드 목록을 반환합니다. 다음 생성식에 대해 개별적으로 정의됩니다:

ClassElementList : ClassElement
  1. ClassElementClassElementKindnon-constructor-method이면,
    1. « ClassElement »를 반환한다.
  2. 새로운 빈 List를 반환한다.
ClassElementList : ClassElementList ClassElement
  1. listNonConstructorElements of ClassElementList로 한다.
  2. ClassElementClassElementKindnon-constructor-method이면,
    1. ClassElementlist의 끝에 추가한다.
  3. list를 반환한다.

15.7.6 정적 의미론: PrototypePropertyNameList

구문 지향 연산 PrototypePropertyNameList는 인자를 받지 않으며, List 타입의 프로퍼티 키 목록을 반환합니다. 다음 생성식에 대해 개별적으로 정의됩니다:

ClassElementList : ClassElement
  1. propNameClassElementPropName로 한다.
  2. propNameempty이면, 새로운 빈 List를 반환한다.
  3. ClassElementIsStatictrue이면, 새로운 빈 List를 반환한다.
  4. « propName »를 반환한다.
ClassElementList : ClassElementList ClassElement
  1. listPrototypePropertyNameList of ClassElementList로 한다.
  2. propNameClassElementPropName로 한다.
  3. propNameempty이면 list를 반환한다.
  4. ClassElementIsStatictrue이면 list를 반환한다.
  5. list와 « propName »의 리스트 연결을 반환한다.

15.7.7 정적 의미론: AllPrivateIdentifiersValid

구문 지향 연산 AllPrivateIdentifiersValid는 names(문자열의 List) 인자를 받고, Boolean을 반환합니다.

아래에 나열되지 않은 이 명세의 모든 문법 생성식 대안은 암묵적으로 다음의 AllPrivateIdentifiersValid의 기본 정의를 갖습니다:

  1. 파싱 노드의 각 자식 노드 child에 대해,
    1. child가 비터미널의 인스턴스이면,
      1. childAllPrivateIdentifiersValidnames 인자를 넘겨 호출 결과가 false이면, false를 반환한다.
  2. true를 반환한다.
MemberExpression : MemberExpression . PrivateIdentifier
  1. namesPrivateIdentifierStringValue를 포함하면,
    1. MemberExpressionAllPrivateIdentifiersValidnames 인자를 넘겨 호출한 결과를 반환한다.
  2. false를 반환한다.
CallExpression : CallExpression . PrivateIdentifier
  1. namesPrivateIdentifierStringValue를 포함하면,
    1. CallExpressionAllPrivateIdentifiersValidnames 인자를 넘겨 호출한 결과를 반환한다.
  2. false를 반환한다.
OptionalChain : ?. PrivateIdentifier
  1. namesPrivateIdentifierStringValue를 포함하면, true를 반환한다.
  2. false를 반환한다.
OptionalChain : OptionalChain . PrivateIdentifier
  1. namesPrivateIdentifierStringValue를 포함하면,
    1. OptionalChainAllPrivateIdentifiersValidnames 인자를 넘겨 호출한 결과를 반환한다.
  2. false를 반환한다.
ClassBody : ClassElementList
  1. newNamesnamesClassBodyPrivateBoundIdentifiers리스트 연결로 한다.
  2. ClassElementListAllPrivateIdentifiersValidnewNames 인자를 넘겨 호출한 결과를 반환한다.
RelationalExpression : PrivateIdentifier in ShiftExpression
  1. namesPrivateIdentifierStringValue를 포함하면,
    1. ShiftExpressionAllPrivateIdentifiersValidnames 인자를 넘겨 호출한 결과를 반환한다.
  2. false를 반환한다.

15.7.8 정적 의미론: PrivateBoundIdentifiers

구문 지향 연산 PrivateBoundIdentifiers는 인자를 받지 않으며, 문자열의 List를 반환합니다. 다음 생성식에 대해 개별적으로 정의됩니다:

FieldDefinition : ClassElementName Initializeropt
  1. ClassElementNamePrivateBoundIdentifiers를 반환한다.
ClassElementName : PrivateIdentifier
  1. PrivateIdentifierStringValue를 유일한 요소로 갖는 List를 반환한다.
ClassElementName : PropertyName ClassElement : ClassStaticBlock ;
  1. 새로운 빈 List를 반환한다.
ClassElementList : ClassElementList ClassElement
  1. names1ClassElementListPrivateBoundIdentifiers로 한다.
  2. names2ClassElementPrivateBoundIdentifiers로 한다.
  3. names1names2리스트 연결을 반환한다.
MethodDefinition : ClassElementName ( UniqueFormalParameters ) { FunctionBody } get ClassElementName ( ) { FunctionBody } set ClassElementName ( PropertySetParameterList ) { FunctionBody } GeneratorMethod : * ClassElementName ( UniqueFormalParameters ) { GeneratorBody } AsyncMethod : async ClassElementName ( UniqueFormalParameters ) { AsyncFunctionBody } AsyncGeneratorMethod : async * ClassElementName ( UniqueFormalParameters ) { AsyncGeneratorBody }
  1. ClassElementNamePrivateBoundIdentifiers를 반환한다.

15.7.9 정적 의미론: ContainsArguments

구문 지향 연산 ContainsArguments는 인자를 받지 않으며, Boolean을 반환합니다.

아래에 나열되지 않은 이 명세의 모든 문법 생성식 대안은 암묵적으로 다음의 ContainsArguments의 기본 정의를 갖습니다:

  1. 파싱 노드의 각 자식 노드 child에 대해,
    1. child가 비터미널의 인스턴스이면,
      1. childContainsArgumentstrue이면, true를 반환한다.
  2. false를 반환한다.
IdentifierReference : Identifier
  1. IdentifierStringValue"arguments"이면, true를 반환한다.
  2. false를 반환한다.
FunctionDeclaration : function BindingIdentifier ( FormalParameters ) { FunctionBody } function ( FormalParameters ) { FunctionBody } FunctionExpression : function BindingIdentifieropt ( FormalParameters ) { FunctionBody } GeneratorDeclaration : function * BindingIdentifier ( FormalParameters ) { GeneratorBody } function * ( FormalParameters ) { GeneratorBody } GeneratorExpression : function * BindingIdentifieropt ( FormalParameters ) { GeneratorBody } AsyncGeneratorDeclaration : async function * BindingIdentifier ( FormalParameters ) { AsyncGeneratorBody } async function * ( FormalParameters ) { AsyncGeneratorBody } AsyncGeneratorExpression : async function * BindingIdentifieropt ( FormalParameters ) { AsyncGeneratorBody } AsyncFunctionDeclaration : async function BindingIdentifier ( FormalParameters ) { AsyncFunctionBody } async function ( FormalParameters ) { AsyncFunctionBody } AsyncFunctionExpression : async function BindingIdentifieropt ( FormalParameters ) { AsyncFunctionBody }
  1. false를 반환한다.
MethodDefinition : ClassElementName ( UniqueFormalParameters ) { FunctionBody } get ClassElementName ( ) { FunctionBody } set ClassElementName ( PropertySetParameterList ) { FunctionBody } GeneratorMethod : * ClassElementName ( UniqueFormalParameters ) { GeneratorBody } AsyncGeneratorMethod : async * ClassElementName ( UniqueFormalParameters ) { AsyncGeneratorBody } AsyncMethod : async ClassElementName ( UniqueFormalParameters ) { AsyncFunctionBody }
  1. ClassElementNameContainsArguments를 반환한다.

15.7.10 실행 시 의미론: ClassFieldDefinitionEvaluation

구문 지향 연산 ClassFieldDefinitionEvaluation은 homeObject(객체)를 인자로 받고, 내포된 normal completion에서 ClassFieldDefinition Record를 반환하거나, abrupt completion을 반환합니다. 다음 생성식에 대해 개별적으로 정의됩니다:

FieldDefinition : ClassElementName Initializeropt
  1. name을 ? Evaluation of ClassElementName로 한다.
  2. Initializer가 존재하면,
    1. formalParameterList를 다음 생성식의 인스턴스로 한다: FormalParameters : [empty]
    2. env실행 중인 실행 컨텍스트의 LexicalEnvironment로 한다.
    3. privateEnv실행 중인 실행 컨텍스트의 PrivateEnvironment로 한다.
    4. sourceText를 유니코드 코드 포인트의 빈 시퀀스로 한다.
    5. initializerOrdinaryFunctionCreate(%Function.prototype%, sourceText, formalParameterList, Initializer, non-lexical-this, env, privateEnv)로 한다.
    6. MakeMethod(initializer, homeObject)를 수행한다.
    7. initializer.[[ClassFieldInitializerName]]name으로 설정한다.
  3. 그렇지 않으면,
    1. initializerempty로 한다.
  4. ClassFieldDefinition Record { [[Name]]: name, [[Initializer]]: initializer }를 반환한다.
참고
initializer에 대해 생성된 함수는 ECMAScript 코드에서 직접 접근할 수 없습니다.

15.7.11 실행 시 의미론: ClassStaticBlockDefinitionEvaluation

구문 지향 연산 ClassStaticBlockDefinitionEvaluation은 homeObject(객체)를 인자로 받고, ClassStaticBlockDefinition Record를 반환합니다. 다음 생성식에 대해 개별적으로 정의됩니다:

ClassStaticBlock : static { ClassStaticBlockBody }
  1. lex실행 중인 실행 컨텍스트의 LexicalEnvironment로 한다.
  2. privateEnv실행 중인 실행 컨텍스트의 PrivateEnvironment로 한다.
  3. sourceText를 유니코드 코드 포인트의 빈 시퀀스로 한다.
  4. formalParameters를 다음 생성식의 인스턴스로 한다: FormalParameters : [empty]
  5. bodyFunctionOrdinaryFunctionCreate(%Function.prototype%, sourceText, formalParameters, ClassStaticBlockBody, non-lexical-this, lex, privateEnv)로 한다.
  6. MakeMethod(bodyFunction, homeObject)를 수행한다.
  7. ClassStaticBlockDefinition Record { [[BodyFunction]]: bodyFunction }을 반환한다.
참고
함수 bodyFunction은 ECMAScript 코드에서 직접 접근할 수 없습니다.

15.7.12 실행 시 의미론: EvaluateClassStaticBlockBody

구문 지향 연산 EvaluateClassStaticBlockBody는 functionObject(ECMAScript 함수 객체)를 인자로 받고, return completion 또는 throw completion을 반환합니다. 다음 생성식에 대해 개별적으로 정의됩니다:

ClassStaticBlockBody : ClassStaticBlockStatementList
  1. Assert: functionObjectClassStaticBlockDefinitionEvaluation 단계 5에 의해 생성된 합성 함수이다.
  2. FunctionDeclarationInstantiation(functionObject, « »).를 수행한다.
  3. Evaluation of ClassStaticBlockStatementList를 수행한다.
  4. ReturnCompletion(undefined)를 반환한다.

15.7.13 실행 시 의미론: ClassElementEvaluation

구문 지향 연산 ClassElementEvaluation은 object(객체)를 인자로 받고, 내포된 normal completion에서 ClassFieldDefinition Record, ClassStaticBlockDefinition Record, PrivateElement, 또는 unused를 반환하거나, abrupt completion을 반환합니다. 다음 생성식에 대해 개별적으로 정의됩니다:

ClassElement : FieldDefinition ; static FieldDefinition ;
  1. ClassFieldDefinitionEvaluation of FieldDefinitionobject 인자를 넘겨 반환한다.
ClassElement : MethodDefinition static MethodDefinition
  1. MethodDefinitionEvaluation of MethodDefinitionobjectfalse 인자를 넘겨 반환한다.
ClassElement : ClassStaticBlock
  1. ClassStaticBlockDefinitionEvaluation of ClassStaticBlockobject 인자를 넘겨 반환한다.
ClassElement : ;
  1. unused를 반환한다.

15.7.14 실행 시 의미론: ClassDefinitionEvaluation

구문 지향 연산 ClassDefinitionEvaluation은 classBinding(문자열 또는 undefined)과 className(프로퍼티 키 또는 Private Name) 인자를 받고, 내포된 normal completion에서 함수 객체를 반환하거나 abrupt completion을 반환합니다.

참고

명세의 편의를 위해, private 메서드와 접근자는 클래스 인스턴스의 [[PrivateElements]] 슬롯에 private 필드와 함께 포함되어 있습니다. 그러나 어떤 객체든 주어진 클래스에 의해 정의된 모든 private 메서드와 접근자를 가지거나, 아무것도 가지지 않습니다. 이 기능은 구현이 각 메서드 또는 접근자를 개별적으로 추적할 필요 없이, private 메서드와 접근자를 구현할 수 있도록 설계되었습니다.

예를 들어, 구현체는 인스턴스 private 메서드를 해당 Private Name에 직접 연결하고, 각 객체에 대해 어떤 클래스 생성자가 해당 객체를 this 값으로 실행했는지 추적할 수 있습니다. 객체에서 인스턴스 private 메서드를 조회하는 것은, 해당 메서드를 정의한 클래스 생성자가 객체를 초기화했는지 확인하고, Private Name에 연결된 메서드를 반환하는 것으로 구성됩니다.

이는 private 필드와는 다릅니다: 필드 이니셜라이저가 클래스 인스턴스화 중에 throw될 수 있기 때문에, 개별 객체는 주어진 클래스의 private 필드의 일부만 가질 수 있으므로, private 필드는 일반적으로 개별적으로 추적되어야 합니다.

다음 생성식에 대해 개별적으로 정의됩니다:

ClassTail : ClassHeritageopt { ClassBodyopt }
  1. env실행 중인 실행 컨텍스트의 LexicalEnvironment로 한다.
  2. classEnvNewDeclarativeEnvironment(env)로 한다.
  3. classBindingundefined가 아니면,
    1. classEnv.CreateImmutableBinding(classBinding, true)를 수행한다.
  4. outerPrivateEnvironment실행 중인 실행 컨텍스트의 PrivateEnvironment로 한다.
  5. classPrivateEnvironmentNewPrivateEnvironment(outerPrivateEnvironment)로 한다.
  6. ClassBody가 존재하면,
    1. ClassBodyPrivateBoundIdentifiers의 각 문자열 dn에 대해,
      1. classPrivateEnvironment.[[Names]]pn이라는 Private Name이 포함되어 있고, pn.[[Description]]dn인 경우,
        1. Assert: 이는 getter/setter 쌍에만 해당합니다.
      2. 그렇지 않으면,
        1. namedn[[Description]]으로 하는 새로운 Private Name로 한다.
        2. nameclassPrivateEnvironment.[[Names]]에 추가한다.
  7. ClassHeritage가 존재하지 않으면,
    1. protoParent%Object.prototype%로 한다.
    2. constructorParent%Function.prototype%로 한다.
  8. 그렇지 않으면,
    1. 실행 중인 실행 컨텍스트의 LexicalEnvironment를 classEnv로 설정한다.
    2. 참고: 실행 중인 실행 컨텍스트의 PrivateEnvironment는 ClassHeritage 평가 시 outerPrivateEnvironment이다.
    3. superclassRefCompletion(Evaluation of ClassHeritage)로 한다.
    4. 실행 중인 실행 컨텍스트의 LexicalEnvironment를 env로 설정한다.
    5. superclass를 ? GetValue(? superclassRef)로 한다.
    6. superclassnull이면,
      1. protoParentnull로 한다.
      2. constructorParent%Function.prototype%로 한다.
    7. 그렇지 않고 IsConstructor(superclass) 가 false이면,
      1. TypeError 예외를 throw한다.
    8. 그 밖의 경우,
      1. protoParent를 ? Get(superclass, "prototype")로 한다.
      2. protoParent객체가 아니거나 null이 아니라면, TypeError 예외를 throw한다.
      3. constructorParentsuperclass로 한다.
  9. protoOrdinaryObjectCreate(protoParent)로 한다.
  10. ClassBody가 존재하지 않으면 constructorempty로 한다.
  11. 그 밖에는, constructorClassBodyConstructorMethod로 한다.
  12. 실행 중인 실행 컨텍스트의 LexicalEnvironment를 classEnv로 설정한다.
  13. 실행 중인 실행 컨텍스트의 PrivateEnvironment를 classPrivateEnvironment로 설정한다.
  14. constructorempty이면,
    1. defaultConstructor를 아무 인자도 받지 않고, 캡처하지 않으며, 호출 시 다음 단계를 수행하는 새로운 Abstract Closure로 한다:
      1. args를 이 함수에 [[Call]] 또는 [[Construct]]로 전달된 인자의 List로 한다.
      2. NewTarget이 undefined이면, TypeError 예외를 throw한다.
      3. F활성 함수 객체로 한다.
      4. F.[[ConstructorKind]]derived이면,
        1. 참고: 이 분기는 constructor(...args) { super(...args); }와 비슷하게 동작합니다. 가장 눈에 띄는 차이점은 위 ECMAScript 소스 텍스트가 %Symbol.iterator%%Array.prototype%에서 호출하는 반면, 이 함수는 호출하지 않는다는 점입니다.
        2. func를 ! F.[[GetPrototypeOf]]()로 한다.
        3. IsConstructor(func)가 false이면, TypeError 예외를 throw한다.
        4. result를 ? Construct(func, args, NewTarget)로 한다.
      5. 그 밖의 경우,
        1. 참고: 이 분기는 constructor() {}와 비슷하게 동작합니다.
        2. result를 ? OrdinaryCreateFromConstructor(NewTarget, "%Object.prototype%")로 한다.
      6. InitializeInstanceElements(result, F)를 수행한다.
      7. NormalCompletion(result)를 반환한다.
    2. FCreateBuiltinFunction(defaultConstructor, 0, className, « [[ConstructorKind]], [[SourceText]] », 현재 Realm Record, constructorParent)로 한다.
  15. 그 밖의 경우,
    1. constructorInfo를 ! DefineMethod of constructorprotoconstructorParent 인자를 넘겨 호출한 결과로 한다.
    2. FconstructorInfo.[[Closure]]로 한다.
    3. MakeClassConstructor(F)를 수행한다.
    4. SetFunctionName(F, className)을 수행한다.
  16. MakeConstructor(F, false, proto)를 수행한다.
  17. ClassHeritage가 존재하면 F.[[ConstructorKind]]derived로 설정한다.
  18. DefineMethodProperty(proto, "constructor", F, false)를 수행한다.
  19. ClassBody가 존재하지 않으면 elements를 새로운 빈 List로 한다.
  20. 그 밖에는, elementsClassBodyNonConstructorElements로 한다.
  21. instancePrivateMethods를 새로운 빈 List로 한다.
  22. staticPrivateMethods를 새로운 빈 List로 한다.
  23. instanceFields를 새로운 빈 List로 한다.
  24. staticElements를 새로운 빈 List로 한다.
  25. elements의 각 ClassElement e에 대해,
    1. IsStatic of efalse이면,
      1. elementCompletion(ClassElementEvaluation of eproto 인자를 넘겨 호출한 결과)로 한다.
    2. 그 밖에는,
      1. elementCompletion(ClassElementEvaluation of eF 인자를 넘겨 호출한 결과)로 한다.
    3. elementabrupt completion이면,
      1. 실행 중인 실행 컨텍스트의 LexicalEnvironment를 env로 설정한다.
      2. 실행 중인 실행 컨텍스트의 PrivateEnvironment를 outerPrivateEnvironment로 설정한다.
      3. element를 반환한다.
    4. element를 ! element로 설정한다.
    5. elementPrivateElement이면,
      1. Assert: element.[[Kind]]method 또는 accessor이다.
      2. IsStatic of efalse이면, containerinstancePrivateMethods로 한다.
      3. 그 밖에는 containerstaticPrivateMethods로 한다.
      4. containerelement.[[Key]]와 동일한 pe라는 PrivateElement가 포함되어 있다면,
        1. Assert: element.[[Kind]]pe.[[Kind]]는 모두 accessor이다.
        2. element.[[Get]]undefined이면,
          1. combinedPrivateElement { [[Key]]: element.[[Key]], [[Kind]]: accessor, [[Get]]: pe.[[Get]], [[Set]]: element.[[Set]] }로 한다.
        3. 그 밖에는,
          1. combinedPrivateElement { [[Key]]: element.[[Key]], [[Kind]]: accessor, [[Get]]: element.[[Get]], [[Set]]: pe.[[Set]] }로 한다.
        4. containerpecombined로 교체한다.
      5. 그 밖에는,
        1. elementcontainer에 추가한다.
    6. 그 밖에 elementClassFieldDefinition Record이면,
      1. IsStatic of efalse이면, elementinstanceFields에 추가한다.
      2. 그 밖에는 elementstaticElements에 추가한다.
    7. 그 밖에 elementClassStaticBlockDefinition Record이면,
      1. elementstaticElements에 추가한다.
  26. 실행 중인 실행 컨텍스트의 LexicalEnvironment를 env로 설정한다.
  27. classBindingundefined가 아니면,
    1. classEnv.InitializeBinding(classBinding, F)를 수행한다.
  28. F.[[PrivateMethods]]instancePrivateMethods로 설정한다.
  29. F.[[Fields]]instanceFields로 설정한다.
  30. staticPrivateMethods의 각 PrivateElement method에 대해,
    1. PrivateMethodOrAccessorAdd(F, method)를 수행한다.
  31. staticElements의 각 elementRecord에 대해,
    1. elementRecordClassFieldDefinition Record이면,
      1. resultCompletion(DefineField(F, elementRecord))로 한다.
    2. 그 밖에는,
      1. Assert: elementRecordClassStaticBlockDefinition Record이다.
      2. resultCompletion(Call(elementRecord.[[BodyFunction]], F))로 한다.
    3. resultabrupt completion이면,
      1. 실행 중인 실행 컨텍스트의 PrivateEnvironment를 outerPrivateEnvironment로 설정한다.
      2. result를 반환한다.
  32. 실행 중인 실행 컨텍스트의 PrivateEnvironment를 outerPrivateEnvironment로 설정한다.
  33. F를 반환한다.

15.7.15 실행 시 의미론: BindingClassDeclarationEvaluation

구문 지향 연산 BindingClassDeclarationEvaluation은 인자를 받지 않으며, 내포된 normal completion에서 함수 객체를 반환하거나 abrupt completion을 반환합니다. 다음 생성식에 대해 개별적으로 정의됩니다:

ClassDeclaration : class BindingIdentifier ClassTail
  1. classNameBindingIdentifierStringValue로 한다.
  2. value를 ? ClassDefinitionEvaluation of ClassTailclassNameclassName 인자를 넘겨 호출한 결과로 한다.
  3. value.[[SourceText]]ClassDeclaration에 매치된 소스 텍스트로 설정한다.
  4. env실행 중인 실행 컨텍스트의 LexicalEnvironment로 한다.
  5. InitializeBoundName(className, value, env)를 수행한다.
  6. value를 반환한다.
ClassDeclaration : class ClassTail
  1. value를 ? ClassDefinitionEvaluation of ClassTailundefined"default" 인자를 넘겨 호출한 결과로 한다.
  2. value.[[SourceText]]ClassDeclaration에 매치된 소스 텍스트로 설정한다.
  3. value를 반환한다.
참고

ClassDeclaration : class ClassTail ExportDeclaration의 일부로만 나타나며, 바인딩의 생성은 해당 생성식의 평가 작업의 일부로 처리됩니다. 16.2.3.7를 참조하세요.

15.7.16 실행 시 의미론: Evaluation

ClassDeclaration : class BindingIdentifier ClassTail
  1. BindingClassDeclarationEvaluation of this ClassDeclaration를 수행한다.
  2. empty를 반환한다.
참고

ClassDeclaration : class ClassTail ExportDeclaration의 일부로만 나타나며 직접적으로 평가되지 않습니다.

ClassExpression : class ClassTail
  1. value를 ? ClassDefinitionEvaluation of ClassTailundefined"" 인자를 넘겨 호출한 결과로 한다.
  2. value.[[SourceText]]ClassExpression에 매치된 소스 텍스트로 설정한다.
  3. value를 반환한다.
ClassExpression : class BindingIdentifier ClassTail
  1. classNameBindingIdentifierStringValue로 한다.
  2. value를 ? ClassDefinitionEvaluation of ClassTailclassNameclassName 인자를 넘겨 호출한 결과로 한다.
  3. value.[[SourceText]]ClassExpression에 매치된 소스 텍스트로 설정한다.
  4. value를 반환한다.
ClassElementName : PrivateIdentifier
  1. privateIdentifierPrivateIdentifierStringValue로 한다.
  2. privateEnvRec실행 중인 실행 컨텍스트의 PrivateEnvironment로 한다.
  3. namesprivateEnvRec.[[Names]]로 한다.
  4. Assert: names의 정확히 한 요소는 [[Description]]privateIdentifierPrivate Name이다.
  5. privateNamenames에서 [[Description]]privateIdentifierPrivate Name로 한다.
  6. privateName을 반환한다.
ClassStaticBlockStatementList : [empty]
  1. undefined를 반환한다.

15.8 비동기 함수 정의

구문

AsyncFunctionDeclaration[Yield, Await, Default] : async [여기에는 LineTerminator 없음] function BindingIdentifier[?Yield, ?Await] ( FormalParameters[~Yield, +Await] ) { AsyncFunctionBody } [+Default] async [여기에는 LineTerminator 없음] function ( FormalParameters[~Yield, +Await] ) { AsyncFunctionBody } AsyncFunctionExpression : async [여기에는 LineTerminator 없음] function BindingIdentifier[~Yield, +Await]opt ( FormalParameters[~Yield, +Await] ) { AsyncFunctionBody } AsyncMethod[Yield, Await] : async [여기에는 LineTerminator 없음] ClassElementName[?Yield, ?Await] ( UniqueFormalParameters[~Yield, +Await] ) { AsyncFunctionBody } AsyncFunctionBody : FunctionBody[~Yield, +Await] AwaitExpression[Yield] : await UnaryExpression[?Yield, +Await] 참고 1

await[Await] 파라미터가 있을 때 AwaitExpression키워드로 파싱됩니다. [Await] 파라미터는 다음 컨텍스트의 최상위에서 존재하지만, FunctionBody 등의 일부 컨텍스트에서는 비활성일 수 있습니다:

Script가 구문적 목표 기호일 때, [Await] 파라미터가 없으면 await는 식별자로 파싱될 수 있습니다. 다음과 같은 컨텍스트를 포함합니다:

참고 2

YieldExpression과 달리, AwaitExpression의 피연산자를 생략하면 문법 오류입니다. 반드시 await할 대상이 필요합니다.

15.8.1 정적 의미론: 초기 오류

AsyncMethod : async ClassElementName ( UniqueFormalParameters ) { AsyncFunctionBody } AsyncFunctionDeclaration : async function BindingIdentifier ( FormalParameters ) { AsyncFunctionBody } async function ( FormalParameters ) { AsyncFunctionBody } AsyncFunctionExpression : async function BindingIdentifieropt ( FormalParameters ) { AsyncFunctionBody }

15.8.2 실행 시 의미론: InstantiateAsyncFunctionObject

구문 지향 연산 InstantiateAsyncFunctionObject는 env(Environment Record)와 privateEnv(PrivateEnvironment Record 또는 null) 인자를 받고, ECMAScript 함수 객체를 반환합니다. 다음 생성식에 대해 개별적으로 정의됩니다:

AsyncFunctionDeclaration : async function BindingIdentifier ( FormalParameters ) { AsyncFunctionBody }
  1. nameBindingIdentifierStringValue로 한다.
  2. sourceTextAsyncFunctionDeclaration에 매치된 소스 텍스트로 한다.
  3. FOrdinaryFunctionCreate(%AsyncFunction.prototype%, sourceText, FormalParameters, AsyncFunctionBody, non-lexical-this, env, privateEnv)로 한다.
  4. SetFunctionName(F, name)을 수행한다.
  5. F를 반환한다.
AsyncFunctionDeclaration : async function ( FormalParameters ) { AsyncFunctionBody }
  1. sourceTextAsyncFunctionDeclaration에 매치된 소스 텍스트로 한다.
  2. FOrdinaryFunctionCreate(%AsyncFunction.prototype%, sourceText, FormalParameters, AsyncFunctionBody, non-lexical-this, env, privateEnv)로 한다.
  3. SetFunctionName(F, "default")를 수행한다.
  4. F를 반환한다.

15.8.3 실행 시 의미론: InstantiateAsyncFunctionExpression

구문 지향 연산 InstantiateAsyncFunctionExpression은 선택적 인자 name(프로퍼티 키 또는 Private Name)를 받고, ECMAScript 함수 객체를 반환합니다. 다음 생성식에 대해 개별적으로 정의됩니다:

AsyncFunctionExpression : async function ( FormalParameters ) { AsyncFunctionBody }
  1. name이 존재하지 않으면 name""로 설정한다.
  2. env실행 중인 실행 컨텍스트의 LexicalEnvironment로 한다.
  3. privateEnv실행 중인 실행 컨텍스트의 PrivateEnvironment로 한다.
  4. sourceTextAsyncFunctionExpression에 매치된 소스 텍스트로 한다.
  5. closureOrdinaryFunctionCreate(%AsyncFunction.prototype%, sourceText, FormalParameters, AsyncFunctionBody, non-lexical-this, env, privateEnv)로 한다.
  6. SetFunctionName(closure, name)을 수행한다.
  7. closure를 반환한다.
AsyncFunctionExpression : async function BindingIdentifier ( FormalParameters ) { AsyncFunctionBody }
  1. Assert: name이 존재하지 않는다.
  2. nameBindingIdentifierStringValue로 설정한다.
  3. outerEnv실행 중인 실행 컨텍스트의 LexicalEnvironment로 한다.
  4. funcEnvNewDeclarativeEnvironment(outerEnv)로 한다.
  5. funcEnv.CreateImmutableBinding(name, false)을 수행한다.
  6. privateEnv실행 중인 실행 컨텍스트의 PrivateEnvironment로 한다.
  7. sourceTextAsyncFunctionExpression에 매치된 소스 텍스트로 한다.
  8. closureOrdinaryFunctionCreate(%AsyncFunction.prototype%, sourceText, FormalParameters, AsyncFunctionBody, non-lexical-this, funcEnv, privateEnv)로 한다.
  9. SetFunctionName(closure, name)을 수행한다.
  10. funcEnv.InitializeBinding(name, closure)을 수행한다.
  11. closure를 반환한다.
참고

BindingIdentifierAsyncFunctionExpression에 포함되어 있을 경우, AsyncFunctionExpressionAsyncFunctionBody 내부에서 참조할 수 있으므로 함수 코드가 자기 자신을 재귀적으로 호출할 수 있습니다. 그러나 FunctionDeclaration의 경우와는 달리, BindingIdentifierAsyncFunctionExpression에 포함되어 있을 경우, AsyncFunctionExpression을 둘러싼 스코프에서 참조할 수 없으며, 그 스코프에 영향을 주지 않습니다.

15.8.4 실행 시 의미론: EvaluateAsyncFunctionBody

구문 지향 연산 EvaluateAsyncFunctionBody는 functionObject(ECMAScript 함수 객체)와 argumentsList(List 타입의 ECMAScript 언어 값 목록) 인자를 받고, return completion을 반환합니다. 다음 생성식에 대해 개별적으로 정의됩니다:

AsyncFunctionBody : FunctionBody
  1. promiseCapability를 ! NewPromiseCapability(%Promise%)로 한다.
  2. completionCompletion(FunctionDeclarationInstantiation(functionObject, argumentsList))로 한다.
  3. completionabrupt completion이면,
    1. Call(promiseCapability.[[Reject]], undefined, « completion.[[Value]] »)를 수행한다.
  4. 그 밖에는,
    1. AsyncFunctionStart(promiseCapability, FunctionBody)를 수행한다.
  5. ReturnCompletion(promiseCapability.[[Promise]])를 반환한다.

15.8.5 실행 시 의미론: Evaluation

AsyncFunctionExpression : async function BindingIdentifieropt ( FormalParameters ) { AsyncFunctionBody }
  1. InstantiateAsyncFunctionExpression of AsyncFunctionExpression를 반환한다.
AwaitExpression : await UnaryExpression
  1. exprRef를 ? Evaluation of UnaryExpression로 한다.
  2. value를 ? GetValue(exprRef)로 한다.
  3. Await(value)를 반환한다.

15.9 비동기 화살표 함수 정의

구문

AsyncArrowFunction[In, Yield, Await] : async [여기에는 LineTerminator 없음] AsyncArrowBindingIdentifier[?Yield] [여기에는 LineTerminator 없음] => AsyncConciseBody[?In] CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await] [여기에는 LineTerminator 없음] => AsyncConciseBody[?In] AsyncConciseBody[In] : [lookahead ≠ {] ExpressionBody[?In, +Await] { AsyncFunctionBody } AsyncArrowBindingIdentifier[Yield] : BindingIdentifier[?Yield, +Await] CoverCallExpressionAndAsyncArrowHead[Yield, Await] : MemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await]

보충 구문

다음 생성식의 인스턴스를 처리할 때
AsyncArrowFunction : CoverCallExpressionAndAsyncArrowHead => AsyncConciseBody
CoverCallExpressionAndAsyncArrowHead의 해석은 다음 문법을 사용하여 정제됩니다:

AsyncArrowHead : async [여기에는 LineTerminator 없음] ArrowFormalParameters[~Yield, +Await]

15.9.1 정적 의미론: 초기 오류

AsyncArrowFunction : async AsyncArrowBindingIdentifier => AsyncConciseBody AsyncArrowFunction : CoverCallExpressionAndAsyncArrowHead => AsyncConciseBody

15.9.2 정적 의미론: AsyncConciseBodyContainsUseStrict

구문 지향 연산 AsyncConciseBodyContainsUseStrict는 인자를 받지 않으며, Boolean을 반환합니다. 다음 생성식에 대해 개별적으로 정의됩니다:

AsyncConciseBody : ExpressionBody
  1. false를 반환한다.
AsyncConciseBody : { AsyncFunctionBody }
  1. AsyncFunctionBodyFunctionBodyContainsUseStrict를 반환한다.

15.9.3 실행 시 의미론: EvaluateAsyncConciseBody

구문 지향 연산 EvaluateAsyncConciseBody는 functionObject(ECMAScript 함수 객체)와 argumentsList(List 타입의 ECMAScript 언어 값 목록) 인자를 받고, return completion을 반환합니다. 다음 생성식에 대해 개별적으로 정의됩니다:

AsyncConciseBody : ExpressionBody
  1. promiseCapability를 ! NewPromiseCapability(%Promise%)로 한다.
  2. completionCompletion(FunctionDeclarationInstantiation(functionObject, argumentsList))로 한다.
  3. completionabrupt completion이면,
    1. Call(promiseCapability.[[Reject]], undefined, « completion.[[Value]] »)를 수행한다.
  4. 그 밖에는,
    1. AsyncFunctionStart(promiseCapability, ExpressionBody)를 수행한다.
  5. ReturnCompletion(promiseCapability.[[Promise]])를 반환한다.

15.9.4 실행 시 의미론: InstantiateAsyncArrowFunctionExpression

구문 지향 연산 InstantiateAsyncArrowFunctionExpression은 선택적 인자 name(프로퍼티 키 또는 Private Name)를 받고, ECMAScript 함수 객체를 반환합니다. 다음 생성식에 대해 개별적으로 정의됩니다:

AsyncArrowFunction : async AsyncArrowBindingIdentifier => AsyncConciseBody
  1. name이 존재하지 않으면 name""로 설정한다.
  2. env실행 중인 실행 컨텍스트의 LexicalEnvironment로 한다.
  3. privateEnv실행 중인 실행 컨텍스트의 PrivateEnvironment로 한다.
  4. sourceTextAsyncArrowFunction에 매치된 소스 텍스트로 한다.
  5. parametersAsyncArrowBindingIdentifier로 한다.
  6. closureOrdinaryFunctionCreate(%AsyncFunction.prototype%, sourceText, parameters, AsyncConciseBody, lexical-this, env, privateEnv)로 한다.
  7. SetFunctionName(closure, name)을 수행한다.
  8. closure를 반환한다.
AsyncArrowFunction : CoverCallExpressionAndAsyncArrowHead => AsyncConciseBody
  1. name이 존재하지 않으면 name""로 설정한다.
  2. env실행 중인 실행 컨텍스트의 LexicalEnvironment로 한다.
  3. privateEnv실행 중인 실행 컨텍스트의 PrivateEnvironment로 한다.
  4. sourceTextAsyncArrowFunction에 매치된 소스 텍스트로 한다.
  5. headAsyncArrowHead로 한다. 이는 CoverCallExpressionAndAsyncArrowHead에 의해 덮여진 것이다.
  6. parametersheadArrowFormalParameters로 한다.
  7. closureOrdinaryFunctionCreate(%AsyncFunction.prototype%, sourceText, parameters, AsyncConciseBody, lexical-this, env, privateEnv)로 한다.
  8. SetFunctionName(closure, name)을 수행한다.
  9. closure를 반환한다.

15.9.5 실행 시 의미론: 평가

AsyncArrowFunction : async AsyncArrowBindingIdentifier => AsyncConciseBody CoverCallExpressionAndAsyncArrowHead => AsyncConciseBody
  1. InstantiateAsyncArrowFunctionExpression of AsyncArrowFunction를 반환한다.

15.10 꼬리 위치 호출

15.10.1 정적 의미: IsInTailPosition ( call )

추상 연산 IsInTailPosition은 call ( CallExpression 구문 노드, MemberExpression 구문 노드, 또는 OptionalChain 구문 노드)를 인수로 받아 Boolean을 반환합니다. 호출 시 다음 단계를 수행합니다:

  1. IsStrict(call)이 false이면, false를 반환합니다.
  2. callFunctionBody, ConciseBody, 또는 AsyncConciseBody에 포함되어 있지 않으면, false를 반환합니다.
  3. bodyFunctionBody, ConciseBody, 또는 AsyncConciseBodycall을 가장 밀접하게 포함하는 것으로 설정합니다.
  4. bodyFunctionBodyGeneratorBody라면, false를 반환합니다.
  5. bodyFunctionBodyAsyncFunctionBody라면, false를 반환합니다.
  6. bodyFunctionBodyAsyncGeneratorBody라면, false를 반환합니다.
  7. bodyAsyncConciseBody라면, false를 반환합니다.
  8. body와 인수 callHasCallInTailPosition의 결과를 반환합니다.
참고

꼬리 위치 호출은 엄격 모드 코드에서만 정의됩니다. 이는 호출자 컨텍스트 체인의 관찰을 가능하게 하는 일반적인 비표준 언어 확장(10.2.4) 때문입니다.

15.10.2 정적 의미: HasCallInTailPosition

구문-지향 연산 HasCallInTailPosition은 call ( CallExpression 구문 노드, MemberExpression 구문 노드, 또는 OptionalChain 구문 노드)를 인수로 받아 Boolean을 반환합니다.

참고 1

call은 특정 소스 텍스트 범위를 나타내는 구문 노드입니다. 아래 알고리즘이 call을 다른 구문 노드와 비교할 때, 이는 동일한 소스 텍스트를 나타내는지 테스트하는 것입니다.

참고 2

반환 GetValue 결과가 즉시 뒤따르는 잠재적 꼬리 위치 호출도 꼬리 위치 호출이 될 수 있습니다. 함수 호출은 참조 레코드를 반환할 수 없으므로, 이러한 GetValue 연산은 항상 실제 함수 호출 결과와 동일한 값을 반환합니다.

다음 생성 규칙에 따라 개별적으로 정의됩니다:

StatementList : StatementList StatementListItem
  1. hasHasCallInTailPositionStatementList와 인수 call의 결과로 설정한다.
  2. hastrue이면, true를 반환한다.
  3. HasCallInTailPositionStatementListItem와 인수 call의 결과를 반환한다.
FunctionStatementList : [empty] StatementListItem : Declaration Statement : VariableStatement EmptyStatement ExpressionStatement ContinueStatement BreakStatement ThrowStatement DebuggerStatement Block : { } ReturnStatement : return ; LabelledItem : FunctionDeclaration ForInOfStatement : for ( LeftHandSideExpression of AssignmentExpression ) Statement for ( var ForBinding of AssignmentExpression ) Statement for ( ForDeclaration of AssignmentExpression ) Statement CaseBlock : { }
  1. false를 반환한다.
IfStatement : if ( Expression ) Statement else Statement
  1. has를 첫 번째 Statement와 인수 callHasCallInTailPosition의 결과로 설정한다.
  2. hastrue이면, true를 반환한다.
  3. 두 번째 Statement와 인수 callHasCallInTailPosition의 결과를 반환한다.
IfStatement : if ( Expression ) Statement DoWhileStatement : do Statement while ( Expression ) ; WhileStatement : while ( Expression ) Statement ForStatement : for ( Expressionopt ; Expressionopt ; Expressionopt ) Statement for ( var VariableDeclarationList ; Expressionopt ; Expressionopt ) Statement for ( LexicalDeclaration Expressionopt ; Expressionopt ) Statement ForInOfStatement : for ( LeftHandSideExpression in Expression ) Statement for ( var ForBinding in Expression ) Statement for ( ForDeclaration in Expression ) Statement WithStatement : with ( Expression ) Statement
  1. HasCallInTailPositionStatement와 인수 call의 결과를 반환한다.
LabelledStatement : LabelIdentifier : LabelledItem
  1. HasCallInTailPositionLabelledItem와 인수 call의 결과를 반환한다.
ReturnStatement : return Expression ;
  1. HasCallInTailPositionExpression와 인수 call의 결과를 반환한다.
SwitchStatement : switch ( Expression ) CaseBlock
  1. HasCallInTailPositionCaseBlock와 인수 call의 결과를 반환한다.
CaseBlock : { CaseClausesopt DefaultClause CaseClausesopt }
  1. hasfalse로 설정한다.
  2. 첫 번째 CaseClauses가 존재하면, has를 첫 번째 CaseClauses와 인수 callHasCallInTailPosition의 결과로 설정한다.
  3. hastrue이면, true를 반환한다.
  4. hasDefaultClause와 인수 callHasCallInTailPosition의 결과로 설정한다.
  5. hastrue이면, true를 반환한다.
  6. 두 번째 CaseClauses가 존재하면, has를 두 번째 CaseClauses와 인수 callHasCallInTailPosition의 결과로 설정한다.
  7. has를 반환한다.
CaseClauses : CaseClauses CaseClause
  1. hasCaseClauses와 인수 callHasCallInTailPosition의 결과로 설정한다.
  2. hastrue이면, true를 반환한다.
  3. CaseClause와 인수 callHasCallInTailPosition의 결과를 반환한다.
CaseClause : case Expression : StatementListopt DefaultClause : default : StatementListopt
  1. StatementList가 존재하면, HasCallInTailPositionStatementList와 인수 call의 결과를 반환한다.
  2. false를 반환한다.
TryStatement : try Block Catch
  1. HasCallInTailPositionCatch와 인수 call의 결과를 반환한다.
TryStatement : try Block Finally try Block Catch Finally
  1. HasCallInTailPositionFinally와 인수 call의 결과를 반환한다.
Catch : catch ( CatchParameter ) Block
  1. HasCallInTailPositionBlock와 인수 call의 결과를 반환한다.
AssignmentExpression : YieldExpression ArrowFunction AsyncArrowFunction LeftHandSideExpression = AssignmentExpression LeftHandSideExpression AssignmentOperator AssignmentExpression LeftHandSideExpression &&= AssignmentExpression LeftHandSideExpression ||= AssignmentExpression LeftHandSideExpression ??= AssignmentExpression BitwiseANDExpression : BitwiseANDExpression & EqualityExpression BitwiseXORExpression : BitwiseXORExpression ^ BitwiseANDExpression BitwiseORExpression : BitwiseORExpression | BitwiseXORExpression EqualityExpression : EqualityExpression == RelationalExpression EqualityExpression != RelationalExpression EqualityExpression === RelationalExpression EqualityExpression !== RelationalExpression RelationalExpression : RelationalExpression < ShiftExpression RelationalExpression > ShiftExpression RelationalExpression <= ShiftExpression RelationalExpression >= ShiftExpression RelationalExpression instanceof ShiftExpression RelationalExpression in ShiftExpression PrivateIdentifier in ShiftExpression ShiftExpression : ShiftExpression << AdditiveExpression ShiftExpression >> AdditiveExpression ShiftExpression >>> AdditiveExpression AdditiveExpression : AdditiveExpression + MultiplicativeExpression AdditiveExpression - MultiplicativeExpression MultiplicativeExpression : MultiplicativeExpression MultiplicativeOperator ExponentiationExpression ExponentiationExpression : UpdateExpression ** ExponentiationExpression UpdateExpression : LeftHandSideExpression ++ LeftHandSideExpression -- ++ UnaryExpression -- UnaryExpression UnaryExpression : delete UnaryExpression void UnaryExpression typeof UnaryExpression + UnaryExpression - UnaryExpression ~ UnaryExpression ! UnaryExpression AwaitExpression CallExpression : SuperCall ImportCall CallExpression [ Expression ] CallExpression . IdentifierName CallExpression . PrivateIdentifier NewExpression : new NewExpression MemberExpression : MemberExpression [ Expression ] MemberExpression . IdentifierName SuperProperty MetaProperty new MemberExpression Arguments MemberExpression . PrivateIdentifier PrimaryExpression : this IdentifierReference Literal ArrayLiteral ObjectLiteral FunctionExpression ClassExpression GeneratorExpression AsyncFunctionExpression AsyncGeneratorExpression RegularExpressionLiteral TemplateLiteral
  1. false를 반환한다.
Expression : AssignmentExpression Expression , AssignmentExpression
  1. HasCallInTailPositionAssignmentExpression와 인수 call의 결과를 반환한다.
ConditionalExpression : ShortCircuitExpression ? AssignmentExpression : AssignmentExpression
  1. has를 첫 번째 AssignmentExpression와 인수 callHasCallInTailPosition의 결과로 설정한다.
  2. hastrue이면, true를 반환한다.
  3. 두 번째 AssignmentExpression와 인수 callHasCallInTailPosition의 결과를 반환한다.
LogicalANDExpression : LogicalANDExpression && BitwiseORExpression
  1. HasCallInTailPositionBitwiseORExpression와 인수 call의 결과를 반환한다.
LogicalORExpression : LogicalORExpression || LogicalANDExpression
  1. HasCallInTailPositionLogicalANDExpression와 인수 call의 결과를 반환한다.
CoalesceExpression : CoalesceExpressionHead ?? BitwiseORExpression
  1. HasCallInTailPositionBitwiseORExpression와 인수 call의 결과를 반환한다.
CallExpression : CoverCallExpressionAndAsyncArrowHead CallExpression Arguments CallExpression TemplateLiteral
  1. CallExpressioncall이면, true를 반환한다.
  2. false를 반환한다.
OptionalExpression : MemberExpression OptionalChain CallExpression OptionalChain OptionalExpression OptionalChain
  1. HasCallInTailPositionOptionalChain와 인수 call의 결과를 반환한다.
OptionalChain : ?. [ Expression ] ?. IdentifierName ?. PrivateIdentifier OptionalChain [ Expression ] OptionalChain . IdentifierName OptionalChain . PrivateIdentifier
  1. false를 반환한다.
OptionalChain : ?. Arguments OptionalChain Arguments
  1. OptionalChaincall이면, true를 반환한다.
  2. false를 반환한다.
MemberExpression : MemberExpression TemplateLiteral
  1. MemberExpressioncall이면, true를 반환한다.
  2. false를 반환한다.
PrimaryExpression : CoverParenthesizedExpressionAndArrowParameterList
  1. exprParenthesizedExpression에서 coveredCoverParenthesizedExpressionAndArrowParameterList로 설정한다.
  2. HasCallInTailPositionexpr와 인수 call의 결과를 반환한다.
ParenthesizedExpression : ( Expression )
  1. HasCallInTailPositionExpression와 인수 call의 결과를 반환한다.

15.10.3 PrepareForTailCall ( )

추상 연산 PrepareForTailCall은 인수를 받지 않으며 unused를 반환한다. 호출 시 다음 단계를 수행한다:

  1. Assert: 현재 execution context는 이후 ECMAScript 코드 또는 내장 함수의 평가에 사용되지 않는다. 이 추상 연산 호출 이후의 Call 호출은 그러한 평가를 수행하기 전에 새로운 execution context를 생성하고 푸시한다.
  2. 현재 execution context와 연관된 모든 리소스를 폐기한다.
  3. unused를 반환한다.

꼬리 위치 호출은 대상 함수를 호출하기 전에 현재 실행 중인 함수의 execution context와 연관된 임시 내부 리소스를 해제하거나, 그 리소스를 대상 함수 지원에 재사용해야 한다.

참고

예를 들어, 꼬리 위치 호출은 구현의 activation record 스택을 대상 함수의 activation record 크기가 호출 함수의 activation record 크기를 초과하는 만큼만 증가시켜야 한다. 만약 대상 함수의 activation record가 더 작다면 전체 스택 크기는 줄어야 한다.

16 ECMAScript 언어: 스크립트와 모듈

16.1 스크립트

구문

Script : ScriptBodyopt ScriptBody : StatementList[~Yield, ~Await, ~Return]

16.1.1 정적 의미: 초기 에러

Script : ScriptBody ScriptBody : StatementList

16.1.2 정적 의미: ScriptIsStrict

구문-지향 연산 ScriptIsStrict는 인수를 받지 않으며 Boolean을 반환한다. 다음 생성 규칙에 따라 개별적으로 정의된다:

Script : ScriptBodyopt
  1. ScriptBody가 존재하고 Directive PrologueUse Strict Directive를 포함하면 true를 반환하고, 그렇지 않으면 false를 반환한다.

16.1.3 실행 의미: 평가

Script : [empty]
  1. undefined를 반환한다.

16.1.4 스크립트 레코드

스크립트 레코드는 평가 중인 스크립트에 대한 정보를 캡슐화한다. 각 스크립트 레코드는 표 39에 나열된 필드를 포함한다.

표 39: 스크립트 레코드 필드
필드 이름 값 타입 의미
[[Realm]] Realm 레코드 이 스크립트가 생성된 realm.
[[ECMAScriptCode]] Script 구문 노드 이 스크립트의 소스 텍스트를 파싱한 결과.
[[LoadedModules]] List of LoadedModuleRequest 레코드 이 스크립트가 import한 명세자 문자열에서 해결된 모듈 레코드에 대한 매핑. 이 리스트에는 레코드 r1r2가 모두 포함될 수 없으며 ModuleRequestsEqual(r1, r2)가 true가 되는 경우는 없다.
[[HostDefined]] 아무 값이나 (기본값은 empty) 호스트 환경이 스크립트에 추가 정보를 연결할 필요가 있을 때 사용하는 필드.

16.1.5 ParseScript ( sourceText, realm, hostDefined )

추상 연산 ParseScript는 sourceText (ECMAScript 소스 텍스트), realm (Realm 레코드), hostDefined (아무 값) 인자를 받아 스크립트 레코드 또는 List (비어있지 않은 SyntaxError 객체 목록)을 반환한다. sourceTextScript로 파싱한 결과에 기반하여 스크립트 레코드를 생성한다. 호출 시 다음 단계를 수행한다:

  1. scriptParseText(sourceText, Script)로 설정한다.
  2. script가 에러의 List라면 script를 반환한다.
  3. 스크립트 레코드 { [[Realm]]: realm, [[ECMAScriptCode]]: script, [[LoadedModules]]: « », [[HostDefined]]: hostDefined }를 반환한다.
참고

구현체는 ParseScript가 실제로 해당 소스 텍스트에 대해 수행되기 전에 스크립트 소스 텍스트를 파싱하고 초기 에러 조건을 분석할 수 있다. 하지만 에러 보고는 이 명세가 해당 소스 텍스트에 대해 실제로 ParseScript를 수행하는 시점까지 지연되어야 한다.

16.1.6 ScriptEvaluation ( scriptRecord )

추상 연산 ScriptEvaluation은 scriptRecord (스크립트 레코드)를 인자로 받아 정상 완료(normal completion) (내부에 ECMAScript 언어 값를 포함) 또는 비정상 완료(abrupt completion)를 반환한다. 호출 시 다음 단계를 수행한다:

  1. globalEnvscriptRecord.[[Realm]].[[GlobalEnv]]로 설정한다.
  2. scriptContext를 새로운 ECMAScript 코드 실행 컨텍스트로 설정한다.
  3. scriptContext의 Function을 null로 설정한다.
  4. scriptContextRealmscriptRecord.[[Realm]]으로 설정한다.
  5. scriptContext의 ScriptOrModule을 scriptRecord로 설정한다.
  6. scriptContext의 VariableEnvironment를 globalEnv로 설정한다.
  7. scriptContext의 LexicalEnvironment를 globalEnv로 설정한다.
  8. scriptContext의 PrivateEnvironment를 null로 설정한다.
  9. 실행 중인 실행 컨텍스트를 일시 중지한다.
  10. scriptContext실행 컨텍스트 스택에 푸시한다; scriptContext가 이제 실행 중인 실행 컨텍스트가 된다.
  11. scriptscriptRecord.[[ECMAScriptCode]]로 설정한다.
  12. resultCompletion(GlobalDeclarationInstantiation(script, globalEnv))로 설정한다.
  13. result정상 완료(normal completion)이면,
    1. resultCompletion(Evaluation of script)로 설정한다.
    2. result정상 완료(normal completion)이고 result.[[Value]]empty이면,
      1. resultNormalCompletion(undefined)로 설정한다.
  14. scriptContext를 일시 중지하고 실행 컨텍스트 스택에서 제거한다.
  15. Assert: 실행 컨텍스트 스택는 비어 있지 않다.
  16. 실행 컨텍스트 스택의 최상단에 있는 컨텍스트를 실행 중인 실행 컨텍스트로 복구한다.
  17. result를 반환한다.

16.1.7 GlobalDeclarationInstantiation ( script, env )

추상 연산 GlobalDeclarationInstantiation은 script (Script 구문 노드)와 env (글로벌 환경 레코드)를 인자로 받으며, 정상 완료(normal completion) (unused 포함) 또는 throw completion를 반환한다. scriptexecution context가 설정되는 Script이며, env는 바인딩이 생성될 글로벌 환경이다.

참고 1

스크립트 평가를 위해 execution context가 설정될 때, 선언은 현재 글로벌 환경에 인스턴스화된다. 코드에 선언된 각 글로벌 바인딩이 인스턴스화된다.

호출 시 다음 단계를 수행한다:

  1. lexNamesscriptLexicallyDeclaredNames로 설정한다.
  2. varNamesscriptVarDeclaredNames로 설정한다.
  3. lexNames의 각 요소 name에 대해,
    1. HasLexicalDeclaration(env, name)가 true이면 SyntaxError 예외를 throw한다.
    2. hasRestrictedGlobal를 ? HasRestrictedGlobalProperty(env, name)로 설정한다.
    3. 참고: 글로벌 varfunction 바인딩(비엄격 직접 eval에서 도입된 것을 제외)은 non-configurable이므로 restricted global properties이다.
    4. hasRestrictedGlobaltrue이면 SyntaxError 예외를 throw한다.
  4. varNames의 각 요소 name에 대해,
    1. HasLexicalDeclaration(env, name)가 true이면 SyntaxError 예외를 throw한다.
  5. varDeclarationsscriptVarScopedDeclarations로 설정한다.
  6. functionsToInitialize를 새로운 빈 List로 설정한다.
  7. declaredFunctionNames를 새로운 빈 List로 설정한다.
  8. varDeclarations의 각 요소 d에 대해, 역순 List 순서로,
    1. dVariableDeclaration, ForBinding, BindingIdentifier 모두가 아니라면,
      1. Assert: dFunctionDeclaration, GeneratorDeclaration, AsyncFunctionDeclaration, AsyncGeneratorDeclaration 중 하나이다.
      2. 참고: 동일 이름의 함수 선언이 여러 개면 마지막 선언이 사용된다.
      3. fndBoundNames의 단일 요소로 설정한다.
      4. declaredFunctionNamesfn을 포함하지 않으면,
        1. fnDefinable을 ? CanDeclareGlobalFunction(env, fn)로 설정한다.
        2. fnDefinablefalse이면 TypeError 예외를 throw한다.
        3. fndeclaredFunctionNames에 추가한다.
        4. dfunctionsToInitialize의 첫 번째 요소로 삽입한다.
  9. declaredVarNames를 새로운 빈 List로 설정한다.
  10. varDeclarations의 각 요소 d에 대해,
    1. dVariableDeclaration, ForBinding, BindingIdentifier 중 하나라면,
      1. dBoundNames의 각 문자열 vn에 대해,
        1. declaredFunctionNamesvn을 포함하지 않으면,
          1. vnDefinable을 ? CanDeclareGlobalVar(env, vn)로 설정한다.
          2. vnDefinablefalse이면 TypeError 예외를 throw한다.
          3. declaredVarNamesvn을 포함하지 않으면,
            1. vndeclaredVarNames에 추가한다.
  11. 참고: global objectordinary object이면 이 알고리즘 단계 이후 비정상 종료가 발생하지 않는다. 하지만 global objectProxy exotic object라면 이후 단계에서 비정상 종료를 유발할 수 있다.
  12. 참고: 부록 B.3.2.2에서 이 지점에 추가 단계를 삽입한다.
  13. lexDeclarationsscriptLexicallyScopedDeclarations로 설정한다.
  14. privateEnvnull로 설정한다.
  15. lexDeclarations의 각 요소 d에 대해,
    1. 참고: 렉시컬 선언 이름은 여기서 인스턴스화만 되고 초기화는 되지 않는다.
    2. dBoundNames의 각 요소 dn에 대해,
      1. IsConstantDeclaration(d)가 true이면,
        1. ? env.CreateImmutableBinding(dn, true)를 수행한다.
      2. 그 외에는,
        1. ? env.CreateMutableBinding(dn, false)를 수행한다.
  16. functionsToInitialize의 각 구문 노드 f에 대해,
    1. fnfBoundNames의 단일 요소로 설정한다.
    2. fof에 대해 InstantiateFunctionObjectenvprivateEnv 인자로 호출한 결과로 설정한다.
    3. ? CreateGlobalFunctionBinding(env, fn, fo, false)를 수행한다.
  17. declaredVarNames의 각 문자열 vn에 대해,
    1. ? CreateGlobalVarBinding(env, vn, false)를 수행한다.
  18. unused를 반환한다.
참고 2

초기 에러16.1.1에서 함수/var 선언과 let/const/class 선언 간의 이름 충돌 및 단일 Script 내에서의 let/const/class 바인딩 재선언을 방지한다. 그러나 여러 Script에 걸친 충돌 및 재선언은 GlobalDeclarationInstantiation 실행 중 런타임 에러로 감지된다. 이러한 에러가 감지되면 스크립트에 대해 어떤 바인딩도 인스턴스화되지 않는다. 하지만 global objectProxy exotic object로 정의된 경우, 런타임 충돌 선언 검사가 신뢰할 수 없어 비정상 완료(abrupt completion)와 일부 글로벌 선언이 인스턴스화되지 않을 수 있다. 이 경우 Script의 코드는 평가되지 않는다.

명시적인 var 또는 function 선언과 달리, global object에 직접 생성된 프로퍼티는 let/const/class 선언에 의해 그림자 처리될 수 있다.

16.2 모듈

구문

Module : ModuleBodyopt ModuleBody : ModuleItemList ModuleItemList : ModuleItem ModuleItemList ModuleItem ModuleItem : ImportDeclaration ExportDeclaration StatementListItem[~Yield, +Await, ~Return] ModuleExportName : IdentifierName StringLiteral

16.2.1 모듈 의미론

16.2.1.1 정적 의미: 초기 에러

ModuleBody : ModuleItemList 참고

중복 ExportedNames 규칙은 하나의 ModuleBody 내에 여러 export default ExportDeclaration 항목이 있으면 구문 에러임을 의미한다. 충돌 또는 중복 선언과 관련된 추가 에러 조건은 Module의 평가 이전, 모듈 연결 단계에서 검사된다. 이러한 에러가 감지되면 Module는 평가되지 않는다.

ModuleExportName : StringLiteral

16.2.1.2 정적 의미: ImportedLocalNames( importEntries )

추상 연산 ImportedLocalNames는 importEntries(List of ImportEntry Record)를 인자로 받고, 문자열 List를 반환한다. importEntries로 정의된 모든 지역 이름 바인딩의 List를 생성한다. 호출 시 다음 단계를 수행한다:

  1. localNames를 새로운 빈 List로 설정한다.
  2. importEntries의 각 ImportEntry Record i에 대해,
    1. i.[[LocalName]]localNames에 추가한다.
  3. localNames를 반환한다.

16.2.1.3 ModuleRequest 레코드

ModuleRequest Record는 주어진 import 속성으로 모듈을 import하기 위한 요청을 나타낸다. 다음 필드로 구성된다:

표 40: ModuleRequest Record 필드
필드 이름 값 타입 의미
[[Specifier]] 문자열 모듈 지정자
[[Attributes]] List of ImportAttribute Record import 속성들

LoadedModuleRequest Record는 모듈 import 요청과 결과 Module Record를 함께 나타낸다. 표 40에 정의된 필드에 [[Module]]이 추가된다:

표 41: LoadedModuleRequest Record 필드
필드 이름 값 타입 의미
[[Specifier]] 문자열 모듈 지정자
[[Attributes]] List of ImportAttribute Record import 속성들
[[Module]] Module Record 해당 모듈 요청에 대한 로드된 모듈

ImportAttribute Record는 다음 필드로 구성된다:

표 42: ImportAttribute Record 필드
필드 이름 값 타입 의미
[[Key]] 문자열 속성 key
[[Value]] 문자열 속성 value

16.2.1.3.1 ModuleRequestsEqual ( left, right )

추상 연산 ModuleRequestsEqual은 left(ModuleRequest Record 또는 LoadedModuleRequest Record) 와 right(ModuleRequest Record 또는 LoadedModuleRequest Record) 를 인자로 받고, Boolean을 반환한다. 호출 시 다음 단계를 수행한다:

  1. left.[[Specifier]]right.[[Specifier]]와 다르면 false를 반환한다.
  2. leftAttrsleft.[[Attributes]]로 설정한다.
  3. rightAttrsright.[[Attributes]]로 설정한다.
  4. leftAttrsCountleftAttrs의 요소 개수로 설정한다.
  5. rightAttrsCountrightAttrs의 요소 개수로 설정한다.
  6. leftAttrsCountrightAttrsCount이면 false를 반환한다.
  7. leftAttrs의 각 ImportAttribute Record l에 대해,
    1. rightAttrsl.[[Key]]l.[[Value]]가 동일한 ImportAttribute Record r가 없으면 false를 반환한다.
  8. true를 반환한다.

16.2.1.4 정적 의미: ModuleRequests

구문-지향 연산 ModuleRequests는 인수를 받지 않으며 List of ModuleRequest Record를 반환한다. 다음 생성 규칙에 따라 개별적으로 정의된다:

Module : [empty]
  1. 새로운 빈 List를 반환한다.
ModuleItemList : ModuleItem
  1. ModuleItemModuleRequests를 반환한다.
ModuleItemList : ModuleItemList ModuleItem
  1. requestsModuleItemListModuleRequests로 설정한다.
  2. additionalRequestsModuleItemModuleRequests로 설정한다.
  3. additionalRequests의 각 ModuleRequest Record mr에 대해,
    1. requestsModuleRequest Record mr2가 없고, ModuleRequestsEqual(mr, mr2)가 true가 아니면,
      1. mrrequests에 추가한다.
  4. requests를 반환한다.
ModuleItem : StatementListItem
  1. 새로운 빈 List를 반환한다.
ImportDeclaration : import ImportClause FromClause ;
  1. specifierFromClauseSV로 설정한다.
  2. 유일한 요소가 ModuleRequest Record { [[Specifier]]: specifier, [[Attributes]]: « » }인 List를 반환한다.
ImportDeclaration : import ImportClause FromClause WithClause ;
  1. specifierFromClauseSV로 설정한다.
  2. attributesWithClauseWithClauseToAttributes로 설정한다.
  3. 유일한 요소가 ModuleRequest Record { [[Specifier]]: specifier, [[Attributes]]: attributes }인 List를 반환한다.
ImportDeclaration : import ModuleSpecifier ;
  1. specifierModuleSpecifierSV로 설정한다.
  2. 유일한 요소가 ModuleRequest Record { [[Specifier]]: specifier, [[Attributes]]: « » }인 List를 반환한다.
ImportDeclaration : import ModuleSpecifier WithClause ;
  1. specifierModuleSpecifierSV로 설정한다.
  2. attributesWithClauseWithClauseToAttributes로 설정한다.
  3. 유일한 요소가 ModuleRequest Record { [[Specifier]]: specifier, [[Attributes]]: attributes }인 List를 반환한다.
ExportDeclaration : export ExportFromClause FromClause ;
  1. specifierFromClauseSV로 설정한다.
  2. 유일한 요소가 ModuleRequest Record { [[Specifier]]: specifier, [[Attributes]]: « » }인 List를 반환한다.
ExportDeclaration : export ExportFromClause FromClause WithClause ;
  1. specifierFromClauseSV로 설정한다.
  2. attributesWithClauseWithClauseToAttributes로 설정한다.
  3. 유일한 요소가 ModuleRequest Record { [[Specifier]]: specifier, [[Attributes]]: attributes }인 List를 반환한다.
ExportDeclaration : export NamedExports ; export VariableStatement export Declaration export default HoistableDeclaration export default ClassDeclaration export default AssignmentExpression ;
  1. 새로운 빈 List를 반환한다.

16.2.1.5 추상 모듈 레코드

Module Record는 단일 모듈의 import와 export에 대한 구조적 정보를 캡슐화한다. 이 정보는 연결된 모듈 집합의 import와 export를 연결하는 데 사용된다. Module Record는 모듈을 평가할 때만 사용하는 네 개의 필드를 포함한다.

명세 목적상 Module Record 값은 Record 명세 타입의 값이며, Module Record가 추상 클래스이고 추상 및 구체 서브클래스를 가진 단순 객체지향 계층에 존재한다고 생각할 수 있다. 이 명세서는 Cyclic Module Record라는 추상 서브클래스와 Source Text Module Record라는 구체 서브클래스를 정의한다. 다른 명세와 구현체들은 자신들이 정의한 대안적 모듈 정의 기능에 대응하는 추가적인 Module Record 서브클래스를 정의할 수 있다.

Module Record는 표 43에 나열된 필드를 정의한다. 모든 Module Definition 서브클래스는 최소한 이 필드들을 포함한다. 또한 Module Record는 표 44에 나열된 추상 메서드 목록을 정의한다. 모든 Module Definition 서브클래스는 이 추상 메서드들의 구체 구현을 제공해야 한다.

표 43: Module Record 필드
필드 이름 값 타입 의미
[[Realm]] Realm Record 이 모듈이 생성된 Realm.
[[Environment]] Module Environment Record 또는 empty 이 모듈의 최상위 바인딩을 포함하는 Environment Record. 이 필드는 모듈이 연결될 때 설정된다.
[[Namespace]] 객체 또는 empty 이 모듈에 대해 생성된 경우의 모듈 네임스페이스 객체 (28.3).
[[HostDefined]] 아무 값 (기본값은 undefined) 호스트 환경이 모듈에 추가 정보를 연결할 필요가 있을 때 사용하는 필드.
표 44: Module Record의 추상 메서드
메서드 목적
LoadRequestedModules([hostDefined])

모듈을 연결할 수 있도록 모든 의존성을 재귀적으로 로드하며, 프라미스를 반환한다.

GetExportedNames([exportStarSet])

이 모듈에서 직접 또는 간접적으로 export되는 모든 이름의 리스트를 반환한다.

이 메서드를 호출하기 전에 LoadRequestedModules가 성공적으로 완료되어야 한다.

ResolveExport(exportName [, resolveSet])

이 모듈에서 export된 이름의 바인딩을 반환한다. 바인딩은 { [[Module]]: Module Record, [[BindingName]]: String | namespace } 형태의 ResolvedBinding Record로 표현된다. 만약 export가 어떤 모듈에도 직접 바인딩되지 않은 Module Namespace Object라면 [[BindingName]]namespace로 설정된다. 이름을 해결할 수 없으면 null을, 여러 바인딩이 발견되면 ambiguous를 반환한다.

이 연산이 특정 exportName, resolveSet 쌍으로 호출될 때마다 같은 결과를 반환해야 한다.

이 메서드를 호출하기 전에 LoadRequestedModules가 성공적으로 완료되어야 한다.

Link()

모듈의 평가를 준비하기 위해 모든 모듈 의존성을 추이적으로 해결하고 Module Environment Record를 생성한다.

이 메서드를 호출하기 전에 LoadRequestedModules가 성공적으로 완료되어야 한다.

Evaluate()

이 모듈과 그 의존성의 평가에 대한 프라미스를 반환한다. 평가가 성공하거나 이미 성공적으로 평가된 경우 resolve되며, 평가 에러가 발생하거나 이미 실패한 경우 reject된다. 프라미스가 reject될 경우 호스트는 프라미스 reject를 처리하고 평가 에러를 다시 throw해야 한다.

이 메서드를 호출하기 전에 Link가 성공적으로 완료되어야 한다.

16.2.1.5.1 EvaluateModuleSync ( module )

추상 연산 EvaluateModuleSync는 module(Module Record)를 인자로 받고, 정상 완료(normal completion)(unused 포함) 또는 throw completion를 반환한다. 호출자는 module의 평가가 이미 settle된 프라미스를 반환함을 보장해야 하며, module을 동기적으로 평가한다. 호출 시 다음 단계를 수행한다:

  1. Assert: moduleCyclic Module Record가 아니다.
  2. promisemodule.Evaluate()로 설정한다.
  3. Assert: promise.[[PromiseState]]fulfilled 또는 rejected이다.
  4. promise.[[PromiseState]]rejected이면,
    1. promise.[[PromiseIsHandled]]false이면, HostPromiseRejectionTracker(promise, "handle")를 수행한다.
    2. promise.[[PromiseIsHandled]]true로 설정한다.
    3. ThrowCompletion(promise.[[PromiseResult]])를 반환한다.
  5. unused를 반환한다.

16.2.1.6 Cyclic Module Records

A Cyclic Module Record is used to represent information about a module that can participate in dependency cycles with other modules that are subclasses of the Cyclic Module Record type. Module Records that are not subclasses of the Cyclic Module Record type must not participate in dependency cycles with Source Text Module Records.

In addition to the fields defined in Table 43 Cyclic Module Records have the additional fields listed in Table 45

Table 45: Additional Fields of Cyclic Module Records
Field Name Value Type Meaning
[[Status]] new, unlinked, linking, linked, evaluating, evaluating-async, or evaluated Initially new. Transitions to unlinked, linking, linked, evaluating, possibly evaluating-async, evaluated (in that order) as the module progresses throughout its lifecycle. evaluating-async indicates this module is queued to execute on completion of its asynchronous dependencies or it is a module whose [[HasTLA]] field is true that has been executed and is pending top-level completion.
[[EvaluationError]] a throw completion or empty A throw completion representing the exception that occurred during evaluation. undefined if no exception occurred or if [[Status]] is not evaluated.
[[DFSAncestorIndex]] an integer or empty Auxiliary field used during Link and Evaluate only. If [[Status]] is either linking or evaluating, this is either the module's depth-first traversal index or that of an "earlier" module in the same strongly connected component.
[[RequestedModules]] a List of ModuleRequest Records A List of the ModuleRequest Records associated with the imports in this module. The List is in source text occurrence order of the imports.
[[LoadedModules]] a List of LoadedModuleRequest Records A map from the specifier strings used by the module represented by this record to request the importation of a module with the relative import attributes to the resolved Module Record. The list does not contain two different Records r1 and r2 such that ModuleRequestsEqual(r1, r2) is true.
[[CycleRoot]] a Cyclic Module Record or empty The first visited module of the cycle, the root DFS ancestor of the strongly connected component. For a module not in a cycle, this would be the module itself. Once Evaluate has completed, a module's [[DFSAncestorIndex]] is the depth-first traversal index of its [[CycleRoot]].
[[HasTLA]] a Boolean Whether this module is individually asynchronous (for example, if it's a Source Text Module Record containing a top-level await). Having an asynchronous dependency does not mean this field is true. This field must not change after the module is parsed.
[[AsyncEvaluationOrder]] unset, an integer, or done This field is initially set to unset, and remains unset for fully synchronous modules. For modules that are either themselves asynchronous or have an asynchronous dependency, it is set to an integer that determines the order in which execution of pending modules is queued by 16.2.1.6.1.3.4. Once the pending module is executed, the field is set to done.
[[TopLevelCapability]] a PromiseCapability Record or empty If this module is the [[CycleRoot]] of some cycle, and Evaluate() was called on some module in that cycle, this field contains the PromiseCapability Record for that entire evaluation. It is used to settle the Promise object that is returned from the Evaluate() abstract method. This field will be empty for any dependencies of that module, unless a top-level Evaluate() has been initiated for some of those dependencies.
[[AsyncParentModules]] a List of Cyclic Module Records If this module or a dependency has [[HasTLA]] true, and execution is in progress, this tracks the parent importers of this module for the top-level execution job. These parent modules will not start executing before this module has successfully completed execution.
[[PendingAsyncDependencies]] an integer or empty If this module has any asynchronous dependencies, this tracks the number of asynchronous dependency modules remaining to execute for this module. A module with asynchronous dependencies will be executed when this field reaches 0 and there are no execution errors.

In addition to the methods defined in Table 44 Cyclic Module Records have the additional methods listed in Table 46

Table 46: Additional Abstract Methods of Cyclic Module Records
Method Purpose
InitializeEnvironment() Initialize the Environment Record of the module, including resolving all imported bindings, and create the module's execution context.
ExecuteModule([promiseCapability]) Evaluate the module's code within its execution context. If this module has true in [[HasTLA]], then a PromiseCapability Record is passed as an argument, and the method is expected to resolve or reject the given capability. In this case, the method must not throw an exception, but instead reject the PromiseCapability Record if necessary.

A GraphLoadingState Record is a Record that contains information about the loading process of a module graph. It's used to continue loading after a call to HostLoadImportedModule. Each GraphLoadingState Record has the fields defined in Table 47:

Table 47: GraphLoadingState Record Fields
Field Name Value Type Meaning
[[PromiseCapability]] a PromiseCapability Record The promise to resolve when the loading process finishes.
[[IsLoading]] a Boolean It is true if the loading process has not finished yet, neither successfully nor with an error.
[[PendingModulesCount]] a non-negative integer It tracks the number of pending HostLoadImportedModule calls.
[[Visited]] a List of Cyclic Module Records It is a list of the Cyclic Module Records that have been already loaded by the current loading process, to avoid infinite loops with circular dependencies.
[[HostDefined]] anything (default value is empty) It contains host-defined data to pass from the LoadRequestedModules caller to HostLoadImportedModule.

16.2.1.6.1 Implementation of Module Record Abstract Methods

The following are the concrete methods for Cyclic Module Record that implement the corresponding Module Record abstract methods defined in Table 44.

16.2.1.6.1.1 LoadRequestedModules ( [ hostDefined ] )

The LoadRequestedModules concrete method of a Cyclic Module Record module takes optional argument hostDefined (anything) and returns a Promise. It populates the [[LoadedModules]] of all the Module Records in the dependency graph of module (most of the work is done by the auxiliary function InnerModuleLoading). It takes an optional hostDefined parameter that is passed to the HostLoadImportedModule hook. It performs the following steps when called:

  1. If hostDefined is not present, let hostDefined be empty.
  2. Let pc be ! NewPromiseCapability(%Promise%).
  3. Let state be the GraphLoadingState Record { [[IsLoading]]: true, [[PendingModulesCount]]: 1, [[Visited]]: « », [[PromiseCapability]]: pc, [[HostDefined]]: hostDefined }.
  4. Perform InnerModuleLoading(state, module).
  5. Return pc.[[Promise]].
Note
The hostDefined parameter can be used to pass additional information necessary to fetch the imported modules. It is used, for example, by HTML to set the correct fetch destination for <link rel="preload" as="..."> tags. import() expressions never set the hostDefined parameter.

16.2.1.6.1.1.1 InnerModuleLoading ( state, module )

The abstract operation InnerModuleLoading takes arguments state (a GraphLoadingState Record) and module (a Module Record) and returns unused. It is used by LoadRequestedModules to recursively perform the actual loading process for module's dependency graph. It performs the following steps when called:

  1. Assert: state.[[IsLoading]] is true.
  2. If module is a Cyclic Module Record, module.[[Status]] is new, and state.[[Visited]] does not contain module, then
    1. Append module to state.[[Visited]].
    2. Let requestedModulesCount be the number of elements in module.[[RequestedModules]].
    3. Set state.[[PendingModulesCount]] to state.[[PendingModulesCount]] + requestedModulesCount.
    4. For each ModuleRequest Record request of module.[[RequestedModules]], do
      1. If AllImportAttributesSupported(request.[[Attributes]]) is false, then
        1. Let error be ThrowCompletion(a newly created SyntaxError object).
        2. Perform ContinueModuleLoading(state, error).
      2. Else if module.[[LoadedModules]] contains a LoadedModuleRequest Record record such that ModuleRequestsEqual(record, request) is true, then
        1. Perform InnerModuleLoading(state, record.[[Module]]).
      3. Else,
        1. Perform HostLoadImportedModule(module, request, state.[[HostDefined]], state).
        2. NOTE: HostLoadImportedModule will call FinishLoadingImportedModule, which re-enters the graph loading process through ContinueModuleLoading.
      4. If state.[[IsLoading]] is false, return unused.
  3. Assert: state.[[PendingModulesCount]] ≥ 1.
  4. Set state.[[PendingModulesCount]] to state.[[PendingModulesCount]] - 1.
  5. If state.[[PendingModulesCount]] = 0, then
    1. Set state.[[IsLoading]] to false.
    2. For each Cyclic Module Record loaded of state.[[Visited]], do
      1. If loaded.[[Status]] is new, set loaded.[[Status]] to unlinked.
    3. Perform ! Call(state.[[PromiseCapability]].[[Resolve]], undefined, « undefined »).
  6. Return unused.

16.2.1.6.1.1.2 ContinueModuleLoading ( state, moduleCompletion )

The abstract operation ContinueModuleLoading takes arguments state (a GraphLoadingState Record) and moduleCompletion (either a normal completion containing a Module Record or a throw completion) and returns unused. It is used to re-enter the loading process after a call to HostLoadImportedModule. It performs the following steps when called:

  1. If state.[[IsLoading]] is false, return unused.
  2. If moduleCompletion is a normal completion, then
    1. Perform InnerModuleLoading(state, moduleCompletion.[[Value]]).
  3. Else,
    1. Set state.[[IsLoading]] to false.
    2. Perform ! Call(state.[[PromiseCapability]].[[Reject]], undefined, « moduleCompletion.[[Value]] »).
  4. Return unused.

16.2.1.6.1.2 Link ( )

The Link concrete method of a Cyclic Module Record module takes no arguments and returns either a normal completion containing unused or a throw completion. On success, Link transitions this module's [[Status]] from unlinked to linked. On failure, an exception is thrown and this module's [[Status]] remains unlinked. (Most of the work is done by the auxiliary function InnerModuleLinking.) It performs the following steps when called:

  1. Assert: module.[[Status]] is one of unlinked, linked, evaluating-async, or evaluated.
  2. Let stack be a new empty List.
  3. Let result be Completion(InnerModuleLinking(module, stack, 0)).
  4. If result is an abrupt completion, then
    1. For each Cyclic Module Record m of stack, do
      1. Assert: m.[[Status]] is linking.
      2. Set m.[[Status]] to unlinked.
    2. Assert: module.[[Status]] is unlinked.
    3. Return ? result.
  5. Assert: module.[[Status]] is one of linked, evaluating-async, or evaluated.
  6. Assert: stack is empty.
  7. Return unused.

16.2.1.6.1.2.1 InnerModuleLinking ( module, stack, index )

The abstract operation InnerModuleLinking takes arguments module (a Module Record), stack (a List of Cyclic Module Records), and index (a non-negative integer) and returns either a normal completion containing a non-negative integer or a throw completion. It is used by Link to perform the actual linking process for module, as well as recursively on all other modules in the dependency graph. The stack and index parameters, as well as a module's [[DFSAncestorIndex]] field, keep track of the depth-first search (DFS) traversal. In particular, [[DFSAncestorIndex]] is used to discover strongly connected components (SCCs), such that all modules in an SCC transition to linked together. It performs the following steps when called:

  1. If module is not a Cyclic Module Record, then
    1. Perform ? module.Link().
    2. Return index.
  2. If module.[[Status]] is one of linking, linked, evaluating-async, or evaluated, then
    1. Return index.
  3. Assert: module.[[Status]] is unlinked.
  4. Set module.[[Status]] to linking.
  5. Let moduleIndex be index.
  6. Set module.[[DFSAncestorIndex]] to index.
  7. Set index to index + 1.
  8. Append module to stack.
  9. For each ModuleRequest Record request of module.[[RequestedModules]], do
    1. Let requiredModule be GetImportedModule(module, request).
    2. Set index to ? InnerModuleLinking(requiredModule, stack, index).
    3. If requiredModule is a Cyclic Module Record, then
      1. Assert: requiredModule.[[Status]] is one of linking, linked, evaluating-async, or evaluated.
      2. Assert: requiredModule.[[Status]] is linking if and only if stack contains requiredModule.
      3. If requiredModule.[[Status]] is linking, then
        1. Set module.[[DFSAncestorIndex]] to min(module.[[DFSAncestorIndex]], requiredModule.[[DFSAncestorIndex]]).
  10. Perform ? module.InitializeEnvironment().
  11. Assert: module occurs exactly once in stack.
  12. Assert: module.[[DFSAncestorIndex]]moduleIndex.
  13. If module.[[DFSAncestorIndex]] = moduleIndex, then
    1. Let done be false.
    2. Repeat, while done is false,
      1. Let requiredModule be the last element of stack.
      2. Remove the last element of stack.
      3. Assert: requiredModule is a Cyclic Module Record.
      4. Set requiredModule.[[Status]] to linked.
      5. If requiredModule and module are the same Module Record, set done to true.
  14. Return index.

16.2.1.6.1.3 Evaluate ( )

The Evaluate concrete method of a Cyclic Module Record module takes no arguments and returns a Promise. Evaluate transitions this module's [[Status]] from linked to either evaluating-async or evaluated. The first time it is called on a module in a given strongly connected component, Evaluate creates and returns a Promise which resolves when the module has finished evaluating. This Promise is stored in the [[TopLevelCapability]] field of the [[CycleRoot]] for the component. Future invocations of Evaluate on any module in the component return the same Promise. (Most of the work is done by the auxiliary function InnerModuleEvaluation.) It performs the following steps when called:

  1. Assert: This call to Evaluate is not happening at the same time as another call to Evaluate within the surrounding agent.
  2. Assert: module.[[Status]] is one of linked, evaluating-async, or evaluated.
  3. If module.[[Status]] is either evaluating-async or evaluated, set module to module.[[CycleRoot]].
  4. If module.[[TopLevelCapability]] is not empty, then
    1. Return module.[[TopLevelCapability]].[[Promise]].
  5. Let stack be a new empty List.
  6. Let capability be ! NewPromiseCapability(%Promise%).
  7. Set module.[[TopLevelCapability]] to capability.
  8. Let result be Completion(InnerModuleEvaluation(module, stack, 0)).
  9. If result is an abrupt completion, then
    1. For each Cyclic Module Record m of stack, do
      1. Assert: m.[[Status]] is evaluating.
      2. Assert: m.[[AsyncEvaluationOrder]] is unset.
      3. Set m.[[Status]] to evaluated.
      4. Set m.[[EvaluationError]] to result.
    2. Assert: module.[[Status]] is evaluated.
    3. Assert: module.[[EvaluationError]] and result are the same Completion Record.
    4. Perform ! Call(capability.[[Reject]], undefined, « result.[[Value]] »).
  10. Else,
    1. Assert: module.[[Status]] is either evaluating-async or evaluated.
    2. Assert: module.[[EvaluationError]] is empty.
    3. If module.[[Status]] is evaluated, then
      1. NOTE: This implies that evaluation of module completed synchronously.
      2. Assert: module.[[AsyncEvaluationOrder]] is unset.
      3. Perform ! Call(capability.[[Resolve]], undefined, « undefined »).
    4. Assert: stack is empty.
  11. Return capability.[[Promise]].

16.2.1.6.1.3.1 InnerModuleEvaluation ( module, stack, index )

The abstract operation InnerModuleEvaluation takes arguments module (a Module Record), stack (a List of Cyclic Module Records), and index (a non-negative integer) and returns either a normal completion containing a non-negative integer or a throw completion. It is used by Evaluate to perform the actual evaluation process for module, as well as recursively on all other modules in the dependency graph. The stack and index parameters, as well as module's [[DFSAncestorIndex]] field, are used the same way as in InnerModuleLinking. It performs the following steps when called:

  1. If module is not a Cyclic Module Record, then
    1. Perform ? EvaluateModuleSync(module).
    2. Return index.
  2. If module.[[Status]] is either evaluating-async or evaluated, then
    1. If module.[[EvaluationError]] is empty, return index.
    2. Otherwise, return ? module.[[EvaluationError]].
  3. If module.[[Status]] is evaluating, return index.
  4. Assert: module.[[Status]] is linked.
  5. Set module.[[Status]] to evaluating.
  6. Let moduleIndex be index.
  7. Set module.[[DFSAncestorIndex]] to index.
  8. Set module.[[PendingAsyncDependencies]] to 0.
  9. Set index to index + 1.
  10. Append module to stack.
  11. For each ModuleRequest Record request of module.[[RequestedModules]], do
    1. Let requiredModule be GetImportedModule(module, request).
    2. Set index to ? InnerModuleEvaluation(requiredModule, stack, index).
    3. If requiredModule is a Cyclic Module Record, then
      1. Assert: requiredModule.[[Status]] is one of evaluating, evaluating-async, or evaluated.
      2. Assert: requiredModule.[[Status]] is evaluating if and only if stack contains requiredModule.
      3. If requiredModule.[[Status]] is evaluating, then
        1. Set module.[[DFSAncestorIndex]] to min(module.[[DFSAncestorIndex]], requiredModule.[[DFSAncestorIndex]]).
      4. Else,
        1. Set requiredModule to requiredModule.[[CycleRoot]].
        2. Assert: requiredModule.[[Status]] is either evaluating-async or evaluated.
        3. If requiredModule.[[EvaluationError]] is not empty, return ? requiredModule.[[EvaluationError]].
      5. If requiredModule.[[AsyncEvaluationOrder]] is an integer, then
        1. Set module.[[PendingAsyncDependencies]] to module.[[PendingAsyncDependencies]] + 1.
        2. Append module to requiredModule.[[AsyncParentModules]].
  12. If module.[[PendingAsyncDependencies]] > 0 or module.[[HasTLA]] is true, then
    1. Assert: module.[[AsyncEvaluationOrder]] is unset.
    2. Set module.[[AsyncEvaluationOrder]] to IncrementModuleAsyncEvaluationCount().
    3. If module.[[PendingAsyncDependencies]] = 0, perform ExecuteAsyncModule(module).
  13. Else,
    1. Perform ? module.ExecuteModule().
  14. Assert: module occurs exactly once in stack.
  15. Assert: module.[[DFSAncestorIndex]]moduleIndex.
  16. If module.[[DFSAncestorIndex]] = moduleIndex, then
    1. Let done be false.
    2. Repeat, while done is false,
      1. Let requiredModule be the last element of stack.
      2. Remove the last element of stack.
      3. Assert: requiredModule is a Cyclic Module Record.
      4. Assert: requiredModule.[[AsyncEvaluationOrder]] is either an integer or unset.
      5. If requiredModule.[[AsyncEvaluationOrder]] is unset, set requiredModule.[[Status]] to evaluated.
      6. Otherwise, set requiredModule.[[Status]] to evaluating-async.
      7. If requiredModule and module are the same Module Record, set done to true.
      8. Set requiredModule.[[CycleRoot]] to module.
  17. Return index.
Note 1

A module is evaluating while it is being traversed by InnerModuleEvaluation. A module is evaluated on execution completion or evaluating-async during execution if its [[HasTLA]] field is true or if it has asynchronous dependencies.

Note 2

Any modules depending on a module of an asynchronous cycle when that cycle is not evaluating will instead depend on the execution of the root of the cycle via [[CycleRoot]]. This ensures that the cycle state can be treated as a single strongly connected component through its root module state.

16.2.1.6.1.3.2 ExecuteAsyncModule ( module )

The abstract operation ExecuteAsyncModule takes argument module (a Cyclic Module Record) and returns unused. It performs the following steps when called:

  1. Assert: module.[[Status]] is either evaluating or evaluating-async.
  2. Assert: module.[[HasTLA]] is true.
  3. Let capability be ! NewPromiseCapability(%Promise%).
  4. Let fulfilledClosure be a new Abstract Closure with no parameters that captures module and performs the following steps when called:
    1. Perform AsyncModuleExecutionFulfilled(module).
    2. Return NormalCompletion(undefined).
  5. Let onFulfilled be CreateBuiltinFunction(fulfilledClosure, 0, "", « »).
  6. Let rejectedClosure be a new Abstract Closure with parameters (error) that captures module and performs the following steps when called:
    1. Perform AsyncModuleExecutionRejected(module, error).
    2. Return NormalCompletion(undefined).
  7. Let onRejected be CreateBuiltinFunction(rejectedClosure, 0, "", « »).
  8. Perform PerformPromiseThen(capability.[[Promise]], onFulfilled, onRejected).
  9. Perform ! module.ExecuteModule(capability).
  10. Return unused.

16.2.1.6.1.3.3 GatherAvailableAncestors ( module, execList )

The abstract operation GatherAvailableAncestors takes arguments module (a Cyclic Module Record) and execList (a List of Cyclic Module Records) and returns unused. It performs the following steps when called:

  1. For each Cyclic Module Record m of module.[[AsyncParentModules]], do
    1. If execList does not contain m and m.[[CycleRoot]].[[EvaluationError]] is empty, then
      1. Assert: m.[[Status]] is evaluating-async.
      2. Assert: m.[[EvaluationError]] is empty.
      3. Assert: m.[[AsyncEvaluationOrder]] is an integer.
      4. Assert: m.[[PendingAsyncDependencies]] > 0.
      5. Set m.[[PendingAsyncDependencies]] to m.[[PendingAsyncDependencies]] - 1.
      6. If m.[[PendingAsyncDependencies]] = 0, then
        1. Append m to execList.
        2. If m.[[HasTLA]] is false, perform GatherAvailableAncestors(m, execList).
  2. Return unused.
Note

When an asynchronous execution for a root module is fulfilled, this function determines the list of modules which are able to synchronously execute together on this completion, populating them in execList.

16.2.1.6.1.3.4 AsyncModuleExecutionFulfilled ( module )

The abstract operation AsyncModuleExecutionFulfilled takes argument module (a Cyclic Module Record) and returns unused. It performs the following steps when called:

  1. If module.[[Status]] is evaluated, then
    1. Assert: module.[[EvaluationError]] is not empty.
    2. Return unused.
  2. Assert: module.[[Status]] is evaluating-async.
  3. Assert: module.[[AsyncEvaluationOrder]] is an integer.
  4. Assert: module.[[EvaluationError]] is empty.
  5. Set module.[[AsyncEvaluationOrder]] to done.
  6. Set module.[[Status]] to evaluated.
  7. If module.[[TopLevelCapability]] is not empty, then
    1. Assert: module.[[CycleRoot]] and module are the same Module Record.
    2. Perform ! Call(module.[[TopLevelCapability]].[[Resolve]], undefined, « undefined »).
  8. Let execList be a new empty List.
  9. Perform GatherAvailableAncestors(module, execList).
  10. Assert: All elements of execList have their [[AsyncEvaluationOrder]] field set to an integer, [[PendingAsyncDependencies]] field set to 0, and [[EvaluationError]] field set to empty.
  11. Let sortedExecList be a List whose elements are the elements of execList, sorted by their [[AsyncEvaluationOrder]] field in ascending order.
  12. For each Cyclic Module Record m of sortedExecList, do
    1. If m.[[Status]] is evaluated, then
      1. Assert: m.[[EvaluationError]] is not empty.
    2. Else if m.[[HasTLA]] is true, then
      1. Perform ExecuteAsyncModule(m).
    3. Else,
      1. Let result be m.ExecuteModule().
      2. If result is an abrupt completion, then
        1. Perform AsyncModuleExecutionRejected(m, result.[[Value]]).
      3. Else,
        1. Set m.[[AsyncEvaluationOrder]] to done.
        2. Set m.[[Status]] to evaluated.
        3. If m.[[TopLevelCapability]] is not empty, then
          1. Assert: m.[[CycleRoot]] and m are the same Module Record.
          2. Perform ! Call(m.[[TopLevelCapability]].[[Resolve]], undefined, « undefined »).
  13. Return unused.

16.2.1.6.1.3.5 AsyncModuleExecutionRejected ( module, error )

The abstract operation AsyncModuleExecutionRejected takes arguments module (a Cyclic Module Record) and error (an ECMAScript language value) and returns unused. It performs the following steps when called:

  1. If module.[[Status]] is evaluated, then
    1. Assert: module.[[EvaluationError]] is not empty.
    2. Return unused.
  2. Assert: module.[[Status]] is evaluating-async.
  3. Assert: module.[[AsyncEvaluationOrder]] is an integer.
  4. Assert: module.[[EvaluationError]] is empty.
  5. Set module.[[EvaluationError]] to ThrowCompletion(error).
  6. Set module.[[Status]] to evaluated.
  7. Set module.[[AsyncEvaluationOrder]] to done.
  8. NOTE: module.[[AsyncEvaluationOrder]] is set to done for symmetry with AsyncModuleExecutionFulfilled. In InnerModuleEvaluation, the value of a module's [[AsyncEvaluationOrder]] internal slot is unused when its [[EvaluationError]] internal slot is not empty.
  9. For each Cyclic Module Record m of module.[[AsyncParentModules]], do
    1. Perform AsyncModuleExecutionRejected(m, error).
  10. If module.[[TopLevelCapability]] is not empty, then
    1. Assert: module.[[CycleRoot]] and module are the same Module Record.
    2. Perform ! Call(module.[[TopLevelCapability]].[[Reject]], undefined, « error »).
  11. Return unused.

16.2.1.6.2 Example Cyclic Module Record Graphs

This non-normative section gives a series of examples of the linking and evaluation of a few common module graphs, with a specific focus on how errors can occur.

First consider the following simple module graph:

Figure 2: A simple module graph
A module graph in which module A depends on module B, and module B depends on module C

Let's first assume that there are no error conditions. When a host first calls A.LoadRequestedModules(), this will complete successfully by assumption, and recursively load the dependencies of B and C as well (respectively, C and none), and then set A.[[Status]] = B.[[Status]] = C.[[Status]] = unlinked. Then, when the host calls A.Link(), it will complete successfully (again by assumption) such that A.[[Status]] = B.[[Status]] = C.[[Status]] = linked. These preparatory steps can be performed at any time. Later, when the host is ready to incur any possible side effects of the modules, it can call A.Evaluate(), which will complete successfully, returning a Promise resolving to undefined (again by assumption), recursively having evaluated first C and then B. Each module's [[Status]] at this point will be evaluated.

Consider then cases involving linking errors, after a successful call to A.LoadRequestedModules(). If InnerModuleLinking of C succeeds but, thereafter, fails for B, for example because it imports something that C does not provide, then the original A.Link() will fail, and both A and B's [[Status]] remain unlinked. C's [[Status]] has become linked, though.

Finally, consider a case involving evaluation errors after a successful call to Link(). If InnerModuleEvaluation of C succeeds but, thereafter, fails for B, for example because B contains code that throws an exception, then the original A.Evaluate() will fail, returning a rejected Promise. The resulting exception will be recorded in both A and B's [[EvaluationError]] fields, and their [[Status]] will become evaluated. C will also become evaluated but, in contrast to A and B, will remain without an [[EvaluationError]], as it successfully completed evaluation. Storing the exception ensures that any time a host tries to reuse A or B by calling their Evaluate() method, it will encounter the same exception. (Hosts are not required to reuse Cyclic Module Records; similarly, hosts are not required to expose the exception objects thrown by these methods. However, the specification enables such uses.)

Now consider a different type of error condition:

Figure 3: A module graph with an unresolvable module
A module graph in which module A depends on a missing (unresolvable) module, represented by ???

In this scenario, module A declares a dependency on some other module, but no Module Record exists for that module, i.e. HostLoadImportedModule calls FinishLoadingImportedModule with an exception when asked for it. This could occur for a variety of reasons, such as the corresponding resource not existing, or the resource existing but ParseModule returning some errors when trying to parse the resulting source text. Hosts can choose to expose the cause of failure via the completion they pass to FinishLoadingImportedModule. In any case, this exception causes a loading failure, which results in A's [[Status]] remaining new.

The difference here between loading, linking and evaluation errors is due to the following characteristic:

  • Evaluation must be only performed once, as it can cause side effects; it is thus important to remember whether evaluation has already been performed, even if unsuccessfully. (In the error case, it makes sense to also remember the exception because otherwise subsequent Evaluate() calls would have to synthesize a new one.)
  • Linking, on the other hand, is side-effect-free, and thus even if it fails, it can be retried at a later time with no issues.
  • Loading closely interacts with the host, and it may be desirable for some of them to allow users to retry failed loads (for example, if the failure is caused by temporarily bad network conditions).

Now, consider a module graph with a cycle:

Figure 4: A cyclic module graph
A module graph in which module A depends on module B and C, but module B also depends on module A

Here we assume that the entry point is module A, so that the host proceeds by calling A.LoadRequestedModules(), which performs InnerModuleLoading on A. This in turn calls InnerModuleLoading on B and C. Because of the cycle, this again triggers InnerModuleLoading on A, but at this point it is a no-op since A's dependencies loading has already been triggered during this LoadRequestedModules process. When all the modules in the graph have been successfully loaded, their [[Status]] transitions from new to unlinked at the same time.

Then the host proceeds by calling A.Link(), which performs InnerModuleLinking on A. This in turn calls InnerModuleLinking on B. Because of the cycle, this again triggers InnerModuleLinking on A, but at this point it is a no-op since A.[[Status]] is already linking. B.[[Status]] itself remains linking when control gets back to A and InnerModuleLinking is triggered on C. After this returns with C.[[Status]] being linked, both A and B transition from linking to linked together; this is by design, since they form a strongly connected component. It's possible to transition the status of modules in the same SCC at the same time because during this phase the module graph is traversed with a depth-first search.

An analogous story occurs for the evaluation phase of a cyclic module graph, in the success case.

Now consider a case where A has a linking error; for example, it tries to import a binding from C that does not exist. In that case, the above steps still occur, including the early return from the second call to InnerModuleLinking on A. However, once we unwind back to the original InnerModuleLinking on A, it fails during InitializeEnvironment, namely right after C.ResolveExport(). The thrown SyntaxError exception propagates up to A.Link, which resets all modules that are currently on its stack (these are always exactly the modules that are still linking). Hence both A and B become unlinked. Note that C is left as linked.

Alternatively, consider a case where A has an evaluation error; for example, its source code throws an exception. In that case, the evaluation-time analogue of the above steps still occurs, including the early return from the second call to InnerModuleEvaluation on A. However, once we unwind back to the original InnerModuleEvaluation on A, it fails by assumption. The exception thrown propagates up to A.Evaluate(), which records the error in all modules that are currently on its stack (i.e., the modules that are still evaluating) as well as via [[AsyncParentModules]], which form a chain for modules which contain or depend on top-level await through the whole dependency graph through the AsyncModuleExecutionRejected algorithm. Hence both A and B become evaluated and the exception is recorded in both A and B's [[EvaluationError]] fields, while C is left as evaluated with no [[EvaluationError]].

Lastly, consider a module graph with a cycle, where all modules complete asynchronously:

Figure 5: An asynchronous cyclic module graph
A module graph in which module A depends on module B and C, module B depends on module D, module C depends on module D and E, and module D depends on module A

Loading and linking happen as before, and all modules end up with [[Status]] set to linked.

Calling A.Evaluate() calls InnerModuleEvaluation on A, B, and D, which all transition to evaluating. Then InnerModuleEvaluation is called on A again, which is a no-op because it is already evaluating. At this point, D.[[PendingAsyncDependencies]] is 0, so ExecuteAsyncModule(D) is called and we call D.ExecuteModule with a new PromiseCapability tracking the asynchronous execution of D. We unwind back to the InnerModuleEvaluation on B, setting B.[[PendingAsyncDependencies]] to 1 and B.[[AsyncEvaluationOrder]] to 1. We unwind back to the original InnerModuleEvaluation on A, setting A.[[PendingAsyncDependencies]] to 1. In the next iteration of the loop over A's dependencies, we call InnerModuleEvaluation on C and thus on D (again a no-op) and E. As E has no dependencies and is not part of a cycle, we call ExecuteAsyncModule(E) in the same manner as D and E is immediately removed from the stack. We unwind once more to the InnerModuleEvaluation on C, setting C.[[AsyncEvaluationOrder]] to 3. Now we finish the loop over A's dependencies, set A.[[AsyncEvaluationOrder]] to 4, and remove the entire strongly connected component from the stack, transitioning all of the modules to evaluating-async at once. At this point, the fields of the modules are as given in Table 48.

Table 48: Module fields after the initial Evaluate() call
Field
Module
A B C D E
[[DFSAncestorIndex]] 0 0 0 0 4
[[Status]] evaluating-async evaluating-async evaluating-async evaluating-async evaluating-async
[[AsyncEvaluationOrder]] 4 1 3 0 2
[[AsyncParentModules]] « » « A » « A » « B, C » « C »
[[PendingAsyncDependencies]] 2 (B and C) 1 (D) 2 (D and E) 0 0

Let us assume that E finishes executing first. When that happens, AsyncModuleExecutionFulfilled is called, E.[[Status]] is set to evaluated and C.[[PendingAsyncDependencies]] is decremented to become 1. The fields of the updated modules are as given in Table 49.

Table 49: Module fields after module E finishes executing
Field
Module
C E
[[DFSAncestorIndex]] 0 4
[[Status]] evaluating-async evaluated
[[AsyncEvaluationOrder]] 3 done
[[AsyncParentModules]] « A » « C »
[[PendingAsyncDependencies]] 1 (D) 0

D is next to finish (as it was the only module that was still executing). When that happens, AsyncModuleExecutionFulfilled is called again and D.[[Status]] is set to evaluated. Its ancestors available for execution are B (whose [[AsyncEvaluationOrder]] is 1) and C (whose [[AsyncEvaluationOrder]] is 3), thus B will be handled first: B.[[PendingAsyncDependencies]] is decremented to become 0, ExecuteAsyncModule is called on B, and it starts executing. C.[[PendingAsyncDependencies]] is also decremented to become 0, and C starts executing (potentially in parallel to B if B contains an await). The fields of the updated modules are as given in Table 50.

Table 50: Module fields after module D finishes executing
Field
Module
B C D
[[DFSAncestorIndex]] 0 0 0
[[Status]] evaluating-async evaluating-async evaluated
[[AsyncEvaluationOrder]] 1 3 done
[[AsyncParentModules]] « A » « A » « B, C »
[[PendingAsyncDependencies]] 0 0 0

Let us assume that C finishes executing next. When that happens, AsyncModuleExecutionFulfilled is called again, C.[[Status]] is set to evaluated and A.[[PendingAsyncDependencies]] is decremented to become 1. The fields of the updated modules are as given in Table 51.

Table 51: Module fields after module C finishes executing
Field
Module
A C
[[DFSAncestorIndex]] 0 0
[[Status]] evaluating-async evaluated
[[AsyncEvaluationOrder]] 4 done
[[AsyncParentModules]] « » « A »
[[PendingAsyncDependencies]] 1 (B) 0

Then, B finishes executing. When that happens, AsyncModuleExecutionFulfilled is called again and B.[[Status]] is set to evaluated. A.[[PendingAsyncDependencies]] is decremented to become 0, so ExecuteAsyncModule is called and it starts executing. The fields of the updated modules are as given in Table 52.

Table 52: Module fields after module B finishes executing
Field
Module
A B
[[DFSAncestorIndex]] 0 0
[[Status]] evaluating-async evaluated
[[AsyncEvaluationOrder]] 4 done
[[AsyncParentModules]] « » « A »
[[PendingAsyncDependencies]] 0 0

Finally, A finishes executing. When that happens, AsyncModuleExecutionFulfilled is called again and A.[[Status]] is set to evaluated. At this point, the Promise in A.[[TopLevelCapability]] (which was returned from A.Evaluate()) is resolved, and this concludes the handling of this module graph. The fields of the updated module are as given in Table 53.

Table 53: Module fields after module A finishes executing
Field
Module
A
[[DFSAncestorIndex]] 0
[[Status]] evaluated
[[AsyncEvaluationOrder]] done
[[AsyncParentModules]] « »
[[PendingAsyncDependencies]] 0

Alternatively, consider a failure case where C fails execution and returns an error before B has finished executing. When that happens, AsyncModuleExecutionRejected is called, which sets C.[[Status]] to evaluated and C.[[EvaluationError]] to the error. It then propagates this error to all of the AsyncParentModules by performing AsyncModuleExecutionRejected on each of them. The fields of the updated modules are as given in Table 54.

Table 54: Module fields after module C finishes with an error
Field
Module
A C
[[DFSAncestorIndex]] 0 0
[[Status]] evaluated evaluated
[[AsyncEvaluationOrder]] done done
[[AsyncParentModules]] « » « A »
[[PendingAsyncDependencies]] 1 (B) 0
[[EvaluationError]] empty C's evaluation error

A will be rejected with the same error as C since C will call AsyncModuleExecutionRejected on A with C's error. A.[[Status]] is set to evaluated. At this point the Promise in A.[[TopLevelCapability]] (which was returned from A.Evaluate()) is rejected. The fields of the updated module are as given in Table 55.

Table 55: Module fields after module A is rejected
Field
Module
A
[[DFSAncestorIndex]] 0
[[Status]] evaluated
[[AsyncEvaluationOrder]] done
[[AsyncParentModules]] « »
[[PendingAsyncDependencies]] 0
[[EvaluationError]] C's Evaluation Error

Then, B finishes executing without an error. When that happens, AsyncModuleExecutionFulfilled is called again and B.[[Status]] is set to evaluated. GatherAvailableAncestors is called on B. However, A.[[CycleRoot]] is A which has an evaluation error, so it will not be added to the returned sortedExecList and AsyncModuleExecutionFulfilled will return without further processing. Any future importer of B will resolve the rejection of B.[[CycleRoot]].[[EvaluationError]] from the evaluation error from C that was set on the cycle root A. The fields of the updated modules are as given in Table 56.

Table 56: Module fields after module B finishes executing in an erroring graph
Field
Module
A B
[[DFSAncestorIndex]] 0 0
[[Status]] evaluated evaluated
[[AsyncEvaluationOrder]] 4 1
[[AsyncParentModules]] « » « A »
[[PendingAsyncDependencies]] 0 0
[[EvaluationError]] C's Evaluation Error empty

16.2.1.7 Source Text Module Records

A Source Text Module Record is used to represent information about a module that was defined from ECMAScript source text (11) that was parsed using the goal symbol Module. Its fields contain digested information about the names that are imported and exported by the module, and its concrete methods use these digests to link and evaluate the module.

A Source Text Module Record can exist in a module graph with other subclasses of the abstract Module Record type, and can participate in cycles with other subclasses of the Cyclic Module Record type.

In addition to the fields defined in Table 45, Source Text Module Records have the additional fields listed in Table 57. Each of these fields is initially set in ParseModule.

Table 57: Additional Fields of Source Text Module Records
Field Name Value Type Meaning
[[ECMAScriptCode]] a Parse Node The result of parsing the source text of this module using Module as the goal symbol.
[[Context]] an ECMAScript code execution context or empty The execution context associated with this module. It is empty until the module's environment has been initialized.
[[ImportMeta]] an Object or empty An object exposed through the import.meta meta property. It is empty until it is accessed by ECMAScript code.
[[ImportEntries]] a List of ImportEntry Records A List of ImportEntry records derived from the code of this module.
[[LocalExportEntries]] a List of ExportEntry Records A List of ExportEntry records derived from the code of this module that correspond to declarations that occur within the module.
[[IndirectExportEntries]] a List of ExportEntry Records A List of ExportEntry records derived from the code of this module that correspond to reexported imports that occur within the module or exports from export * as namespace declarations.
[[StarExportEntries]] a List of ExportEntry Records A List of ExportEntry records derived from the code of this module that correspond to export * declarations that occur within the module, not including export * as namespace declarations.

An ImportEntry Record is a Record that digests information about a single declarative import. Each ImportEntry Record has the fields defined in Table 58:

Table 58: ImportEntry Record Fields
Field Name Value Type Meaning
[[ModuleRequest]] a ModuleRequest Record ModuleRequest Record representing the ModuleSpecifier and import attributes of the ImportDeclaration.
[[ImportName]] a String or namespace-object The name under which the desired binding is exported by the module identified by [[ModuleRequest]]. The value namespace-object indicates that the import request is for the target module's namespace object.
[[LocalName]] a String The name that is used to locally access the imported value from within the importing module.
Note 1

Table 59 gives examples of ImportEntry records fields used to represent the syntactic import forms:

Table 59 (Informative): Import Forms Mappings to ImportEntry Records
Import Statement Form [[ModuleRequest]] [[ImportName]] [[LocalName]]
import v from "mod"; "mod" "default" "v"
import * as ns from "mod"; "mod" namespace-object "ns"
import {x} from "mod"; "mod" "x" "x"
import {x as v} from "mod"; "mod" "x" "v"
import "mod"; An ImportEntry Record is not created.

An ExportEntry Record is a Record that digests information about a single declarative export. Each ExportEntry Record has the fields defined in Table 60:

Table 60: ExportEntry Record Fields
Field Name Value Type Meaning
[[ExportName]] a String or null The name used to export this binding by this module.
[[ModuleRequest]] a ModuleRequest Record or null The ModuleRequest Record representing the ModuleSpecifier and import attributes of the ExportDeclaration. null if the ExportDeclaration does not have a ModuleSpecifier.
[[ImportName]] a String, null, all, or all-but-default The name under which the desired binding is exported by the module identified by [[ModuleRequest]]. null if the ExportDeclaration does not have a ModuleSpecifier. all is used for export * as ns from "mod" declarations. all-but-default is used for export * from "mod" declarations.
[[LocalName]] a String or null The name that is used to locally access the exported value from within the importing module. null if the exported value is not locally accessible from within the module.
Note 2

Table 61 gives examples of the ExportEntry record fields used to represent the syntactic export forms:

Table 61 (Informative): Export Forms Mappings to ExportEntry Records
Export Statement Form [[ExportName]] [[ModuleRequest]] [[ImportName]] [[LocalName]]
export var v; "v" null null "v"
export default function f() {} "default" null null "f"
export default function () {} "default" null null "*default*"
export default 42; "default" null null "*default*"
export {x}; "x" null null "x"
export {v as x}; "x" null null "v"
export {x} from "mod"; "x" "mod" "x" null
export {v as x} from "mod"; "x" "mod" "v" null
export * from "mod"; null "mod" all-but-default null
export * as ns from "mod"; "ns" "mod" all null

The following definitions specify the required concrete methods and other abstract operations for Source Text Module Records

16.2.1.7.1 ParseModule ( sourceText, realm, hostDefined )

The abstract operation ParseModule takes arguments sourceText (ECMAScript source text), realm (a Realm Record), and hostDefined (anything) and returns a Source Text Module Record or a non-empty List of SyntaxError objects. It creates a Source Text Module Record based upon the result of parsing sourceText as a Module. It performs the following steps when called:

  1. Let body be ParseText(sourceText, Module).
  2. If body is a List of errors, return body.
  3. Let requestedModules be the ModuleRequests of body.
  4. Let importEntries be the ImportEntries of body.
  5. Let importedBoundNames be ImportedLocalNames(importEntries).
  6. Let indirectExportEntries be a new empty List.
  7. Let localExportEntries be a new empty List.
  8. Let starExportEntries be a new empty List.
  9. Let exportEntries be the ExportEntries of body.
  10. For each ExportEntry Record ee of exportEntries, do
    1. If ee.[[ModuleRequest]] is null, then
      1. If importedBoundNames does not contain ee.[[LocalName]], then
        1. Append ee to localExportEntries.
      2. Else,
        1. Let ie be the element of importEntries whose [[LocalName]] is ee.[[LocalName]].
        2. If ie.[[ImportName]] is namespace-object, then
          1. NOTE: This is a re-export of an imported module namespace object.
          2. Append ee to localExportEntries.
        3. Else,
          1. NOTE: This is a re-export of a single name.
          2. Append the ExportEntry Record { [[ModuleRequest]]: ie.[[ModuleRequest]], [[ImportName]]: ie.[[ImportName]], [[LocalName]]: null, [[ExportName]]: ee.[[ExportName]] } to indirectExportEntries.
    2. Else if ee.[[ImportName]] is all-but-default, then
      1. Assert: ee.[[ExportName]] is null.
      2. Append ee to starExportEntries.
    3. Else,
      1. Append ee to indirectExportEntries.
  11. Let async be body Contains await.
  12. Return Source Text Module Record { [[Realm]]: realm, [[Environment]]: empty, [[Namespace]]: empty, [[CycleRoot]]: empty, [[HasTLA]]: async, [[AsyncEvaluationOrder]]: unset, [[TopLevelCapability]]: empty, [[AsyncParentModules]]: « », [[PendingAsyncDependencies]]: empty, [[Status]]: new, [[EvaluationError]]: empty, [[HostDefined]]: hostDefined, [[ECMAScriptCode]]: body, [[Context]]: empty, [[ImportMeta]]: empty, [[RequestedModules]]: requestedModules, [[LoadedModules]]: « », [[ImportEntries]]: importEntries, [[LocalExportEntries]]: localExportEntries, [[IndirectExportEntries]]: indirectExportEntries, [[StarExportEntries]]: starExportEntries, [[DFSAncestorIndex]]: empty }.
Note

An implementation may parse module source text and analyse it for Early Error conditions prior to the evaluation of ParseModule for that module source text. However, the reporting of any errors must be deferred until the point where this specification actually performs ParseModule upon that source text.

16.2.1.7.2 Implementation of Module Record Abstract Methods

The following are the concrete methods for Source Text Module Record that implement the corresponding Module Record abstract methods defined in Table 44.

16.2.1.7.2.1 GetExportedNames ( [ exportStarSet ] )

The GetExportedNames concrete method of a Source Text Module Record module takes optional argument exportStarSet (a List of Source Text Module Records) and returns a List of Strings. It performs the following steps when called:

  1. Assert: module.[[Status]] is not new.
  2. If exportStarSet is not present, set exportStarSet to a new empty List.
  3. If exportStarSet contains module, then
    1. Assert: We've reached the starting point of an export * circularity.
    2. Return a new empty List.
  4. Append module to exportStarSet.
  5. Let exportedNames be a new empty List.
  6. For each ExportEntry Record e of module.[[LocalExportEntries]], do
    1. Assert: module provides the direct binding for this export.
    2. Assert: e.[[ExportName]] is not null.
    3. Append e.[[ExportName]] to exportedNames.
  7. For each ExportEntry Record e of module.[[IndirectExportEntries]], do
    1. Assert: module imports a specific binding for this export.
    2. Assert: e.[[ExportName]] is not null.
    3. Append e.[[ExportName]] to exportedNames.
  8. For each ExportEntry Record e of module.[[StarExportEntries]], do
    1. Assert: e.[[ModuleRequest]] is not null.
    2. Let requestedModule be GetImportedModule(module, e.[[ModuleRequest]]).
    3. Let starNames be requestedModule.GetExportedNames(exportStarSet).
    4. For each element n of starNames, do
      1. If n is not "default", then
        1. If exportedNames does not contain n, then
          1. Append n to exportedNames.
  9. Return exportedNames.
Note

GetExportedNames does not filter out or throw an exception for names that have ambiguous star export bindings.

16.2.1.7.2.2 ResolveExport ( exportName [ , resolveSet ] )

The ResolveExport concrete method of a Source Text Module Record module takes argument exportName (a String) and optional argument resolveSet (a List of Records with fields [[Module]] (a Module Record) and [[ExportName]] (a String)) and returns a ResolvedBinding Record, null, or ambiguous.

ResolveExport attempts to resolve an imported binding to the actual defining module and local binding name. The defining module may be the module represented by the Module Record this method was invoked on or some other module that is imported by that module. The parameter resolveSet is used to detect unresolved circular import/export paths. If a pair consisting of specific Module Record and exportName is reached that is already in resolveSet, an import circularity has been encountered. Before recursively calling ResolveExport, a pair consisting of module and exportName is added to resolveSet.

If a defining module is found, a ResolvedBinding Record { [[Module]], [[BindingName]] } is returned. This record identifies the resolved binding of the originally requested export, unless this is the export of a namespace with no local binding. In this case, [[BindingName]] will be set to namespace. If no definition was found or the request is found to be circular, null is returned. If the request is found to be ambiguous, ambiguous is returned.

It performs the following steps when called:

  1. Assert: module.[[Status]] is not new.
  2. If resolveSet is not present, set resolveSet to a new empty List.
  3. For each Record { [[Module]], [[ExportName]] } r of resolveSet, do
    1. If module and r.[[Module]] are the same Module Record and exportName is r.[[ExportName]], then
      1. Assert: This is a circular import request.
      2. Return null.
  4. Append the Record { [[Module]]: module, [[ExportName]]: exportName } to resolveSet.
  5. For each ExportEntry Record e of module.[[LocalExportEntries]], do
    1. If e.[[ExportName]] is exportName, then
      1. Assert: module provides the direct binding for this export.
      2. Return ResolvedBinding Record { [[Module]]: module, [[BindingName]]: e.[[LocalName]] }.
  6. For each ExportEntry Record e of module.[[IndirectExportEntries]], do
    1. If e.[[ExportName]] is exportName, then
      1. Assert: e.[[ModuleRequest]] is not null.
      2. Let importedModule be GetImportedModule(module, e.[[ModuleRequest]]).
      3. If e.[[ImportName]] is all, then
        1. Assert: module does not provide the direct binding for this export.
        2. Return ResolvedBinding Record { [[Module]]: importedModule, [[BindingName]]: namespace }.
      4. Else,
        1. Assert: module imports a specific binding for this export.
        2. Assert: e.[[ImportName]] is a String.
        3. Return importedModule.ResolveExport(e.[[ImportName]], resolveSet).
  7. If exportName is "default", then
    1. Assert: A default export was not explicitly defined by this module.
    2. Return null.
    3. NOTE: A default export cannot be provided by an export * from "mod" declaration.
  8. Let starResolution be null.
  9. For each ExportEntry Record e of module.[[StarExportEntries]], do
    1. Assert: e.[[ModuleRequest]] is not null.
    2. Let importedModule be GetImportedModule(module, e.[[ModuleRequest]]).
    3. Let resolution be importedModule.ResolveExport(exportName, resolveSet).
    4. If resolution is ambiguous, return ambiguous.
    5. If resolution is not null, then
      1. Assert: resolution is a ResolvedBinding Record.
      2. If starResolution is null, then
        1. Set starResolution to resolution.
      3. Else,
        1. Assert: There is more than one * import that includes the requested name.
        2. If resolution.[[Module]] and starResolution.[[Module]] are not the same Module Record, return ambiguous.
        3. If resolution.[[BindingName]] is not starResolution.[[BindingName]] and either resolution.[[BindingName]] or starResolution.[[BindingName]] is namespace, return ambiguous.
        4. If resolution.[[BindingName]] is a String, starResolution.[[BindingName]] is a String, and resolution.[[BindingName]] is not starResolution.[[BindingName]], return ambiguous.
  10. Return starResolution.

16.2.1.7.3 Implementation of Cyclic Module Record Abstract Methods

The following are the concrete methods for Source Text Module Record that implement the corresponding Cyclic Module Record abstract methods defined in Table 46.

16.2.1.7.3.1 InitializeEnvironment ( )

The InitializeEnvironment concrete method of a Source Text Module Record module takes no arguments and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:

  1. For each ExportEntry Record e of module.[[IndirectExportEntries]], do
    1. Assert: e.[[ExportName]] is not null.
    2. Let resolution be module.ResolveExport(e.[[ExportName]]).
    3. If resolution is either null or ambiguous, throw a SyntaxError exception.
    4. Assert: resolution is a ResolvedBinding Record.
  2. Assert: All named exports from module are resolvable.
  3. Let realm be module.[[Realm]].
  4. Assert: realm is not undefined.
  5. Let env be NewModuleEnvironment(realm.[[GlobalEnv]]).
  6. Set module.[[Environment]] to env.
  7. For each ImportEntry Record in of module.[[ImportEntries]], do
    1. Let importedModule be GetImportedModule(module, in.[[ModuleRequest]]).
    2. If in.[[ImportName]] is namespace-object, then
      1. Let namespace be GetModuleNamespace(importedModule).
      2. Perform ! env.CreateImmutableBinding(in.[[LocalName]], true).
      3. Perform ! env.InitializeBinding(in.[[LocalName]], namespace).
    3. Else,
      1. Let resolution be importedModule.ResolveExport(in.[[ImportName]]).
      2. If resolution is either null or ambiguous, throw a SyntaxError exception.
      3. If resolution.[[BindingName]] is namespace, then
        1. Let namespace be GetModuleNamespace(resolution.[[Module]]).
        2. Perform ! env.CreateImmutableBinding(in.[[LocalName]], true).
        3. Perform ! env.InitializeBinding(in.[[LocalName]], namespace).
      4. Else,
        1. Perform CreateImportBinding(env, in.[[LocalName]], resolution.[[Module]], resolution.[[BindingName]]).
  8. Let moduleContext be a new ECMAScript code execution context.
  9. Set the Function of moduleContext to null.
  10. Assert: module.[[Realm]] is not undefined.
  11. Set the Realm of moduleContext to module.[[Realm]].
  12. Set the ScriptOrModule of moduleContext to module.
  13. Set the VariableEnvironment of moduleContext to module.[[Environment]].
  14. Set the LexicalEnvironment of moduleContext to module.[[Environment]].
  15. Set the PrivateEnvironment of moduleContext to null.
  16. Set module.[[Context]] to moduleContext.
  17. Push moduleContext onto the execution context stack; moduleContext is now the running execution context.
  18. Let code be module.[[ECMAScriptCode]].
  19. Let varDeclarations be the VarScopedDeclarations of code.
  20. Let declaredVarNames be a new empty List.
  21. For each element d of varDeclarations, do
    1. For each element dn of the BoundNames of d, do
      1. If declaredVarNames does not contain dn, then
        1. Perform ! env.CreateMutableBinding(dn, false).
        2. Perform ! env.InitializeBinding(dn, undefined).
        3. Append dn to declaredVarNames.
  22. Let lexDeclarations be the LexicallyScopedDeclarations of code.
  23. Let privateEnv be null.
  24. For each element d of lexDeclarations, do
    1. For each element dn of the BoundNames of d, do
      1. If IsConstantDeclaration of d is true, then
        1. Perform ! env.CreateImmutableBinding(dn, true).
      2. Else,
        1. Perform ! env.CreateMutableBinding(dn, false).
      3. If d is either a FunctionDeclaration, a GeneratorDeclaration, an AsyncFunctionDeclaration, or an AsyncGeneratorDeclaration, then
        1. Let fo be InstantiateFunctionObject of d with arguments env and privateEnv.
        2. Perform ! env.InitializeBinding(dn, fo).
  25. Remove moduleContext from the execution context stack.
  26. Return unused.

16.2.1.7.3.2 ExecuteModule ( [ capability ] )

The ExecuteModule concrete method of a Source Text Module Record module takes optional argument capability (a PromiseCapability Record) and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:

  1. Let moduleContext be a new ECMAScript code execution context.
  2. Set the Function of moduleContext to null.
  3. Set the Realm of moduleContext to module.[[Realm]].
  4. Set the ScriptOrModule of moduleContext to module.
  5. Assert: module has been linked and declarations in its module environment have been instantiated.
  6. Set the VariableEnvironment of moduleContext to module.[[Environment]].
  7. Set the LexicalEnvironment of moduleContext to module.[[Environment]].
  8. Suspend the running execution context.
  9. If module.[[HasTLA]] is false, then
    1. Assert: capability is not present.
    2. Push moduleContext onto the execution context stack; moduleContext is now the running execution context.
    3. Let result be Completion(Evaluation of module.[[ECMAScriptCode]]).
    4. Suspend moduleContext and remove it from the execution context stack.
    5. Resume the context that is now on the top of the execution context stack as the running execution context.
    6. If result is an abrupt completion, then
      1. Return ? result.
  10. Else,
    1. Assert: capability is a PromiseCapability Record.
    2. Perform AsyncBlockStart(capability, module.[[ECMAScriptCode]], moduleContext).
  11. Return unused.

16.2.1.8 Synthetic Module Records

A Synthetic Module Record is used to represent information about a module that is defined by specifications. Its exported names are statically defined at creation, while their corresponding values can change over time using SetSyntheticModuleExport. It has no imports or dependencies.

Note
A Synthetic Module Record could be used for defining a variety of module types: for example, JSON modules or CSS modules.

In addition to the fields defined in Table 43 Synthetic Module Records have the additional fields listed in Table 62.

Table 62: Additional Fields of Synthetic Module Records
Field Name Value Type Meaning
[[ExportNames]] a List of Strings The names of the exports of the module. This list does not contain duplicates.
[[EvaluationSteps]] an Abstract Closure The initialization logic to perform upon evaluation of the module, taking the Synthetic Module Record as its sole argument. It must not modify [[ExportNames]]. It may return an abrupt completion.

16.2.1.8.1 CreateDefaultExportSyntheticModule ( defaultExport )

The abstract operation CreateDefaultExportSyntheticModule takes argument defaultExport (an ECMAScript language value) and returns a Synthetic Module Record. It creates a Synthetic Module Record whose default export is defaultExport. It performs the following steps when called:

  1. Let realm be the current Realm Record.
  2. Let setDefaultExport be a new Abstract Closure with parameters (module) that captures defaultExport and performs the following steps when called:
    1. Perform SetSyntheticModuleExport(module, "default", defaultExport).
    2. Return NormalCompletion(unused).
  3. Return the Synthetic Module Record { [[Realm]]: realm, [[Environment]]: empty, [[Namespace]]: empty, [[HostDefined]]: undefined, [[ExportNames]]: « "default" », [[EvaluationSteps]]: setDefaultExport }.

16.2.1.8.2 ParseJSONModule ( source )

The abstract operation ParseJSONModule takes argument source (a String) and returns either a normal completion containing a Synthetic Module Record, or a throw completion. It performs the following steps when called:

  1. Let json be ? ParseJSON(source).
  2. Return CreateDefaultExportSyntheticModule(json).

16.2.1.8.3 SetSyntheticModuleExport ( module, exportName, exportValue )

The abstract operation SetSyntheticModuleExport takes arguments module (a Synthetic Module Record), exportName (a String), and exportValue (an ECMAScript language value) and returns unused. It can be used to set or change the exported value for an existing export of a Synthetic Module Record. It performs the following steps when called:

  1. Assert: module.[[ExportNames]] contains exportName.
  2. Let envRec be module.[[Environment]].
  3. Assert: envRec is not empty.
  4. Perform envRec.SetMutableBinding(exportName, exportValue, true).
  5. Return unused.

16.2.1.8.4 Implementation of Module Record Abstract Methods

The following are the concrete methods for Synthetic Module Record that implement the corresponding Module Record abstract methods defined in Table 44.

16.2.1.8.4.1 LoadRequestedModules ( )

The LoadRequestedModules concrete method of a Synthetic Module Record module takes no arguments and returns a Promise. It performs the following steps when called:

  1. Return ! PromiseResolve(%Promise%, undefined).
Note
Synthetic Module Records have no dependencies.

16.2.1.8.4.2 GetExportedNames ( )

The GetExportedNames concrete method of a Synthetic Module Record module takes no arguments and returns a List of Strings. It performs the following steps when called:

  1. Return module.[[ExportNames]].

16.2.1.8.4.3 ResolveExport ( exportName )

The ResolveExport concrete method of a Synthetic Module Record module takes argument exportName (a String) and returns a ResolvedBinding Record or null. It performs the following steps when called:

  1. If module.[[ExportNames]] does not contain exportName, return null.
  2. Return ResolvedBinding Record { [[Module]]: module, [[BindingName]]: exportName }.

16.2.1.8.4.4 Link ( )

The Link concrete method of a Synthetic Module Record module takes no arguments and returns a normal completion containing unused. It performs the following steps when called:

  1. Let realm be module.[[Realm]].
  2. Let env be NewModuleEnvironment(realm.[[GlobalEnv]]).
  3. Set module.[[Environment]] to env.
  4. For each String exportName of module.[[ExportNames]], do
    1. Perform ! env.CreateMutableBinding(exportName, false).
    2. Perform ! env.InitializeBinding(exportName, undefined).
  5. Return NormalCompletion(unused).

16.2.1.8.4.5 Evaluate ( )

The Evaluate concrete method of a Synthetic Module Record module takes no arguments and returns a Promise. It performs the following steps when called:

  1. Let moduleContext be a new ECMAScript code execution context.
  2. Set the Function of moduleContext to null.
  3. Set the Realm of moduleContext to module.[[Realm]].
  4. Set the ScriptOrModule of moduleContext to module.
  5. Set the VariableEnvironment of moduleContext to module.[[Environment]].
  6. Set the LexicalEnvironment of moduleContext to module.[[Environment]].
  7. Suspend the running execution context.
  8. Push moduleContext onto the execution context stack; moduleContext is now the running execution context.
  9. Let steps be module.[[EvaluationSteps]].
  10. Let result be Completion(steps(module)).
  11. Suspend moduleContext and remove it from the execution context stack.
  12. Resume the context that is now on the top of the execution context stack as the running execution context.
  13. Let pc be ! NewPromiseCapability(%Promise%).
  14. IfAbruptRejectPromise(result, pc).
  15. Perform ! Call(pc.[[Resolve]], undefined, « undefined »).
  16. Return pc.[[Promise]].

16.2.1.9 GetImportedModule ( referrer, request )

The abstract operation GetImportedModule takes arguments referrer (a Cyclic Module Record) and request (a ModuleRequest Record) and returns a Module Record. It performs the following steps when called:

  1. Let records be a List consisting of each LoadedModuleRequest Record r of referrer.[[LoadedModules]] such that ModuleRequestsEqual(r, request) is true.
  2. Assert: records has exactly one element, since LoadRequestedModules has completed successfully on referrer prior to invoking this abstract operation.
  3. Let record be the sole element of records.
  4. Return record.[[Module]].

16.2.1.10 HostLoadImportedModule ( referrer, moduleRequest, hostDefined, payload )

The host-defined abstract operation HostLoadImportedModule takes arguments referrer (a Script Record, a Cyclic Module Record, or a Realm Record), moduleRequest (a ModuleRequest Record), hostDefined (anything), and payload (a GraphLoadingState Record or a PromiseCapability Record) and returns unused.

Note 1

An example of when referrer can be a Realm Record is in a web browser host. There, if a user clicks on a control given by

<button type="button" onclick="import('./foo.mjs')">Click me</button>

there will be no active script or module at the time the import() expression runs. More generally, this can happen in any situation where the host pushes execution contexts with null ScriptOrModule components onto the execution context stack.

An implementation of HostLoadImportedModule must conform to the following requirements:

The actual process performed is host-defined, but typically consists of performing whatever I/O operations are necessary to load the appropriate Module Record. Multiple different (referrer, moduleRequest.[[Specifier]], moduleRequest.[[Attributes]]) triples may map to the same Module Record instance. The actual mapping semantics is host-defined but typically a normalization process is applied to specifier as part of the mapping process. A typical normalization process would include actions such as expansion of relative and abbreviated path specifiers.

Note 2

The above text requires that hosts support JSON modules when imported with type: "json" (and HostLoadImportedModule completes normally), but it does not prohibit hosts from supporting JSON modules when imported without type: "json".

16.2.1.11 FinishLoadingImportedModule ( referrer, moduleRequest, payload, result )

The abstract operation FinishLoadingImportedModule takes arguments referrer (a Script Record, a Cyclic Module Record, or a Realm Record), moduleRequest (a ModuleRequest Record), payload (a GraphLoadingState Record or a PromiseCapability Record), and result (either a normal completion containing a Module Record or a throw completion) and returns unused. It performs the following steps when called:

  1. If result is a normal completion, then
    1. If referrer.[[LoadedModules]] contains a LoadedModuleRequest Record record such that ModuleRequestsEqual(record, moduleRequest) is true, then
      1. Assert: record.[[Module]] and result.[[Value]] are the same Module Record.
    2. Else,
      1. Append the LoadedModuleRequest Record { [[Specifier]]: moduleRequest.[[Specifier]], [[Attributes]]: moduleRequest.[[Attributes]], [[Module]]: result.[[Value]] } to referrer.[[LoadedModules]].
  2. If payload is a GraphLoadingState Record, then
    1. Perform ContinueModuleLoading(payload, result).
  3. Else,
    1. Perform ContinueDynamicImport(payload, result).
  4. Return unused.

16.2.1.12 AllImportAttributesSupported ( attributes )

The abstract operation AllImportAttributesSupported takes argument attributes (a List of ImportAttribute Records) and returns a Boolean. It performs the following steps when called:

  1. Let supported be HostGetSupportedImportAttributes().
  2. For each ImportAttribute Record attribute of attributes, do
    1. If supported does not contain attribute.[[Key]], return false.
  3. Return true.

16.2.1.12.1 HostGetSupportedImportAttributes ( )

The host-defined abstract operation HostGetSupportedImportAttributes takes no arguments and returns a List of Strings. It allows host environments to specify which import attributes they support. Only attributes with supported keys will be provided to the host.

An implementation of HostGetSupportedImportAttributes must conform to the following requirements:

  • It must return a List of Strings, each indicating a supported attribute.
  • Each time this operation is called, it must return the same List with the same contents in the same order.

The default implementation of HostGetSupportedImportAttributes is to return a new empty List.

Note
The purpose of requiring the host to specify its supported import attributes, rather than passing all attributes to the host and letting it then choose which ones it wants to handle, is to ensure that unsupported attributes are handled in a consistent way across different hosts.

16.2.1.13 GetModuleNamespace ( module )

The abstract operation GetModuleNamespace takes argument module (an instance of a concrete subclass of Module Record) and returns a Module Namespace Object. It retrieves the Module Namespace Object representing module's exports, lazily creating it the first time it was requested, and storing it in module.[[Namespace]] for future retrieval. It performs the following steps when called:

  1. Assert: If module is a Cyclic Module Record, then module.[[Status]] is not new or unlinked.
  2. Let namespace be module.[[Namespace]].
  3. If namespace is empty, then
    1. Let exportedNames be module.GetExportedNames().
    2. Let unambiguousNames be a new empty List.
    3. For each element name of exportedNames, do
      1. Let resolution be module.ResolveExport(name).
      2. If resolution is a ResolvedBinding Record, append name to unambiguousNames.
    4. Set namespace to ModuleNamespaceCreate(module, unambiguousNames).
  4. Return namespace.
Note

GetModuleNamespace never throws. Instead, unresolvable names are simply excluded from the namespace at this point. They will lead to a real linking error later unless they are all ambiguous star exports that are not explicitly requested anywhere.

16.2.1.14 Runtime Semantics: Evaluation

Module : [empty]
  1. Return undefined.
ModuleBody : ModuleItemList
  1. Let result be Completion(Evaluation of ModuleItemList).
  2. If result is a normal completion and result.[[Value]] is empty, then
    1. Return undefined.
  3. Return ? result.
ModuleItemList : ModuleItemList ModuleItem
  1. Let sl be ? Evaluation of ModuleItemList.
  2. Let s be Completion(Evaluation of ModuleItem).
  3. Return ? UpdateEmpty(s, sl).
Note

The value of a ModuleItemList is the value of the last value-producing item in the ModuleItemList.

ModuleItem : ImportDeclaration
  1. Return empty.

16.2.2 Imports

Syntax

ImportDeclaration : import ImportClause FromClause WithClauseopt ; import ModuleSpecifier WithClauseopt ; ImportClause : ImportedDefaultBinding NameSpaceImport NamedImports ImportedDefaultBinding , NameSpaceImport ImportedDefaultBinding , NamedImports ImportedDefaultBinding : ImportedBinding NameSpaceImport : * as ImportedBinding NamedImports : { } { ImportsList } { ImportsList , } FromClause : from ModuleSpecifier ImportsList : ImportSpecifier ImportsList , ImportSpecifier ImportSpecifier : ImportedBinding ModuleExportName as ImportedBinding ModuleSpecifier : StringLiteral ImportedBinding : BindingIdentifier[~Yield, +Await] WithClause : with { } with { WithEntries ,opt } WithEntries : AttributeKey : StringLiteral AttributeKey : StringLiteral , WithEntries AttributeKey : IdentifierName StringLiteral

16.2.2.1 Static Semantics: Early Errors

ModuleItem : ImportDeclaration WithClause : with { WithEntries ,opt }

16.2.2.2 Static Semantics: ImportEntries

The syntax-directed operation ImportEntries takes no arguments and returns a List of ImportEntry Records. It is defined piecewise over the following productions:

Module : [empty]
  1. Return a new empty List.
ModuleItemList : ModuleItemList ModuleItem
  1. Let entries1 be the ImportEntries of ModuleItemList.
  2. Let entries2 be the ImportEntries of ModuleItem.
  3. Return the list-concatenation of entries1 and entries2.
ModuleItem : ExportDeclaration StatementListItem
  1. Return a new empty List.
ImportDeclaration : import ImportClause FromClause WithClauseopt ;
  1. Let module be the sole element of the ModuleRequests of ImportDeclaration.
  2. Return the ImportEntriesForModule of ImportClause with argument module.
ImportDeclaration : import ModuleSpecifier WithClauseopt ;
  1. Return a new empty List.

16.2.2.3 Static Semantics: ImportEntriesForModule

The syntax-directed operation ImportEntriesForModule takes argument module (a ModuleRequest Record) and returns a List of ImportEntry Records. It is defined piecewise over the following productions:

ImportClause : ImportedDefaultBinding , NameSpaceImport
  1. Let entries1 be the ImportEntriesForModule of ImportedDefaultBinding with argument module.
  2. Let entries2 be the ImportEntriesForModule of NameSpaceImport with argument module.
  3. Return the list-concatenation of entries1 and entries2.
ImportClause : ImportedDefaultBinding , NamedImports
  1. Let entries1 be the ImportEntriesForModule of ImportedDefaultBinding with argument module.
  2. Let entries2 be the ImportEntriesForModule of NamedImports with argument module.
  3. Return the list-concatenation of entries1 and entries2.
ImportedDefaultBinding : ImportedBinding
  1. Let localName be the sole element of the BoundNames of ImportedBinding.
  2. Let defaultEntry be the ImportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: "default", [[LocalName]]: localName }.
  3. Return « defaultEntry ».
NameSpaceImport : * as ImportedBinding
  1. Let localName be the StringValue of ImportedBinding.
  2. Let entry be the ImportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: namespace-object, [[LocalName]]: localName }.
  3. Return « entry ».
NamedImports : { }
  1. Return a new empty List.
ImportsList : ImportsList , ImportSpecifier
  1. Let specs1 be the ImportEntriesForModule of ImportsList with argument module.
  2. Let specs2 be the ImportEntriesForModule of ImportSpecifier with argument module.
  3. Return the list-concatenation of specs1 and specs2.
ImportSpecifier : ImportedBinding
  1. Let localName be the sole element of the BoundNames of ImportedBinding.
  2. Let entry be the ImportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: localName, [[LocalName]]: localName }.
  3. Return « entry ».
ImportSpecifier : ModuleExportName as ImportedBinding
  1. Let importName be the StringValue of ModuleExportName.
  2. Let localName be the StringValue of ImportedBinding.
  3. Let entry be the ImportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: importName, [[LocalName]]: localName }.
  4. Return « entry ».

16.2.2.4 Static Semantics: WithClauseToAttributes

The syntax-directed operation WithClauseToAttributes takes no arguments and returns a List of ImportAttribute Records. It is defined piecewise over the following productions:

WithClause : with { }
  1. Return a new empty List.
WithClause : with { WithEntries ,opt }
  1. Let attributes be WithClauseToAttributes of WithEntries.
  2. Sort attributes according to the lexicographic order of their [[Key]] field, treating the value of each such field as a sequence of UTF-16 code unit values. NOTE: This sorting is observable only in that hosts are prohibited from changing behaviour based on the order in which attributes are enumerated.
  3. Return attributes.
WithEntries : AttributeKey : StringLiteral
  1. Let key be the PropName of AttributeKey.
  2. Let entry be the ImportAttribute Record { [[Key]]: key, [[Value]]: the SV of StringLiteral }.
  3. Return « entry ».
WithEntries : AttributeKey : StringLiteral , WithEntries
  1. Let key be the PropName of AttributeKey.
  2. Let entry be the ImportAttribute Record { [[Key]]: key, [[Value]]: the SV of StringLiteral }.
  3. Let rest be WithClauseToAttributes of WithEntries.
  4. Return the list-concatenation of « entry » and rest.

16.2.3 Exports

Syntax

ExportDeclaration : export ExportFromClause FromClause WithClauseopt ; export NamedExports ; export VariableStatement[~Yield, +Await] export Declaration[~Yield, +Await] export default HoistableDeclaration[~Yield, +Await, +Default] export default ClassDeclaration[~Yield, +Await, +Default] export default [lookahead ∉ { function, async [no LineTerminator here] function, class }] AssignmentExpression[+In, ~Yield, +Await] ; ExportFromClause : * * as ModuleExportName NamedExports NamedExports : { } { ExportsList } { ExportsList , } ExportsList : ExportSpecifier ExportsList , ExportSpecifier ExportSpecifier : ModuleExportName ModuleExportName as ModuleExportName

16.2.3.1 Static Semantics: Early Errors

ExportDeclaration : export NamedExports ; Note

The above rule means that each ReferencedBindings of NamedExports is treated as an IdentifierReference.

16.2.3.2 Static Semantics: ExportedBindings

The syntax-directed operation ExportedBindings takes no arguments and returns a List of Strings.

Note

ExportedBindings are the locally bound names that are explicitly associated with a Module's ExportedNames.

It is defined piecewise over the following productions:

ModuleItemList : ModuleItemList ModuleItem
  1. Let names1 be the ExportedBindings of ModuleItemList.
  2. Let names2 be the ExportedBindings of ModuleItem.
  3. Return the list-concatenation of names1 and names2.
ModuleItem : ImportDeclaration StatementListItem
  1. Return a new empty List.
ExportDeclaration : export ExportFromClause FromClause WithClauseopt ;
  1. Return a new empty List.
ExportDeclaration : export NamedExports ;
  1. Return the ExportedBindings of NamedExports.
ExportDeclaration : export VariableStatement
  1. Return the BoundNames of VariableStatement.
ExportDeclaration : export Declaration
  1. Return the BoundNames of Declaration.
ExportDeclaration : export default HoistableDeclaration export default ClassDeclaration export default AssignmentExpression ;
  1. Return the BoundNames of this ExportDeclaration.
NamedExports : { }
  1. Return a new empty List.
ExportsList : ExportsList , ExportSpecifier
  1. Let names1 be the ExportedBindings of ExportsList.
  2. Let names2 be the ExportedBindings of ExportSpecifier.
  3. Return the list-concatenation of names1 and names2.
ExportSpecifier : ModuleExportName
  1. Return a List whose sole element is the StringValue of ModuleExportName.
ExportSpecifier : ModuleExportName as ModuleExportName
  1. Return a List whose sole element is the StringValue of the first ModuleExportName.

16.2.3.3 Static Semantics: ExportedNames

The syntax-directed operation ExportedNames takes no arguments and returns a List of Strings.

Note

ExportedNames are the externally visible names that a Module explicitly maps to one of its local name bindings.

It is defined piecewise over the following productions:

ModuleItemList : ModuleItemList ModuleItem
  1. Let names1 be the ExportedNames of ModuleItemList.
  2. Let names2 be the ExportedNames of ModuleItem.
  3. Return the list-concatenation of names1 and names2.
ModuleItem : ExportDeclaration
  1. Return the ExportedNames of ExportDeclaration.
ModuleItem : ImportDeclaration StatementListItem
  1. Return a new empty List.
ExportDeclaration : export ExportFromClause FromClause WithClauseopt ;
  1. Return the ExportedNames of ExportFromClause.
ExportFromClause : *
  1. Return a new empty List.
ExportFromClause : * as ModuleExportName
  1. Return a List whose sole element is the StringValue of ModuleExportName.
ExportFromClause : NamedExports
  1. Return the ExportedNames of NamedExports.
ExportDeclaration : export VariableStatement
  1. Return the BoundNames of VariableStatement.
ExportDeclaration : export Declaration
  1. Return the BoundNames of Declaration.
ExportDeclaration : export default HoistableDeclaration export default ClassDeclaration export default AssignmentExpression ;
  1. Return « "default" ».
NamedExports : { }
  1. Return a new empty List.
ExportsList : ExportsList , ExportSpecifier
  1. Let names1 be the ExportedNames of ExportsList.
  2. Let names2 be the ExportedNames of ExportSpecifier.
  3. Return the list-concatenation of names1 and names2.
ExportSpecifier : ModuleExportName
  1. Return a List whose sole element is the StringValue of ModuleExportName.
ExportSpecifier : ModuleExportName as ModuleExportName
  1. Return a List whose sole element is the StringValue of the second ModuleExportName.

16.2.3.4 Static Semantics: ExportEntries

The syntax-directed operation ExportEntries takes no arguments and returns a List of ExportEntry Records. It is defined piecewise over the following productions:

Module : [empty]
  1. Return a new empty List.
ModuleItemList : ModuleItemList ModuleItem
  1. Let entries1 be the ExportEntries of ModuleItemList.
  2. Let entries2 be the ExportEntries of ModuleItem.
  3. Return the list-concatenation of entries1 and entries2.
ModuleItem : ImportDeclaration StatementListItem
  1. Return a new empty List.
ExportDeclaration : export ExportFromClause FromClause WithClauseopt ;
  1. Let module be the sole element of the ModuleRequests of ExportDeclaration.
  2. Return the ExportEntriesForModule of ExportFromClause with argument module.
ExportDeclaration : export NamedExports ;
  1. Return the ExportEntriesForModule of NamedExports with argument null.
ExportDeclaration : export VariableStatement
  1. Let entries be a new empty List.
  2. Let names be the BoundNames of VariableStatement.
  3. For each element name of names, do
    1. Append the ExportEntry Record { [[ModuleRequest]]: null, [[ImportName]]: null, [[LocalName]]: name, [[ExportName]]: name } to entries.
  4. Return entries.
ExportDeclaration : export Declaration
  1. Let entries be a new empty List.
  2. Let names be the BoundNames of Declaration.
  3. For each element name of names, do
    1. Append the ExportEntry Record { [[ModuleRequest]]: null, [[ImportName]]: null, [[LocalName]]: name, [[ExportName]]: name } to entries.
  4. Return entries.
ExportDeclaration : export default HoistableDeclaration
  1. Let names be the BoundNames of HoistableDeclaration.
  2. Let localName be the sole element of names.
  3. Return a List whose sole element is a new ExportEntry Record { [[ModuleRequest]]: null, [[ImportName]]: null, [[LocalName]]: localName, [[ExportName]]: "default" }.
ExportDeclaration : export default ClassDeclaration
  1. Let names be the BoundNames of ClassDeclaration.
  2. Let localName be the sole element of names.
  3. Return a List whose sole element is a new ExportEntry Record { [[ModuleRequest]]: null, [[ImportName]]: null, [[LocalName]]: localName, [[ExportName]]: "default" }.
ExportDeclaration : export default AssignmentExpression ;
  1. Let entry be the ExportEntry Record { [[ModuleRequest]]: null, [[ImportName]]: null, [[LocalName]]: "*default*", [[ExportName]]: "default" }.
  2. Return « entry ».
Note

"*default*" is used within this specification as a synthetic name for anonymous default export values. See this note for more details.

16.2.3.5 Static Semantics: ExportEntriesForModule

The syntax-directed operation ExportEntriesForModule takes argument module (a ModuleRequest Record or null) and returns a List of ExportEntry Records. It is defined piecewise over the following productions:

ExportFromClause : *
  1. Let entry be the ExportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: all-but-default, [[LocalName]]: null, [[ExportName]]: null }.
  2. Return « entry ».
ExportFromClause : * as ModuleExportName
  1. Let exportName be the StringValue of ModuleExportName.
  2. Let entry be the ExportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: all, [[LocalName]]: null, [[ExportName]]: exportName }.
  3. Return « entry ».
NamedExports : { }
  1. Return a new empty List.
ExportsList : ExportsList , ExportSpecifier
  1. Let specs1 be the ExportEntriesForModule of ExportsList with argument module.
  2. Let specs2 be the ExportEntriesForModule of ExportSpecifier with argument module.
  3. Return the list-concatenation of specs1 and specs2.
ExportSpecifier : ModuleExportName
  1. Let sourceName be the StringValue of ModuleExportName.
  2. If module is null, then
    1. Let localName be sourceName.
    2. Let importName be null.
  3. Else,
    1. Let localName be null.
    2. Let importName be sourceName.
  4. Return a List whose sole element is a new ExportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: importName, [[LocalName]]: localName, [[ExportName]]: sourceName }.
ExportSpecifier : ModuleExportName as ModuleExportName
  1. Let sourceName be the StringValue of the first ModuleExportName.
  2. Let exportName be the StringValue of the second ModuleExportName.
  3. If module is null, then
    1. Let localName be sourceName.
    2. Let importName be null.
  4. Else,
    1. Let localName be null.
    2. Let importName be sourceName.
  5. Return a List whose sole element is a new ExportEntry Record { [[ModuleRequest]]: module, [[ImportName]]: importName, [[LocalName]]: localName, [[ExportName]]: exportName }.

16.2.3.6 Static Semantics: ReferencedBindings

The syntax-directed operation ReferencedBindings takes no arguments and returns a List of Parse Nodes. It is defined piecewise over the following productions:

NamedExports : { }
  1. Return a new empty List.
ExportsList : ExportsList , ExportSpecifier
  1. Let names1 be the ReferencedBindings of ExportsList.
  2. Let names2 be the ReferencedBindings of ExportSpecifier.
  3. Return the list-concatenation of names1 and names2.
ExportSpecifier : ModuleExportName as ModuleExportName
  1. Return the ReferencedBindings of the first ModuleExportName.
ModuleExportName : IdentifierName
  1. Return a List whose sole element is the IdentifierName.
ModuleExportName : StringLiteral
  1. Return a List whose sole element is the StringLiteral.

16.2.3.7 Runtime Semantics: Evaluation

ExportDeclaration : export ExportFromClause FromClause WithClauseopt ; export NamedExports ;
  1. Return empty.
ExportDeclaration : export VariableStatement
  1. Return ? Evaluation of VariableStatement.
ExportDeclaration : export Declaration
  1. Return ? Evaluation of Declaration.
ExportDeclaration : export default HoistableDeclaration
  1. Return ? Evaluation of HoistableDeclaration.
ExportDeclaration : export default ClassDeclaration
  1. Let value be ? BindingClassDeclarationEvaluation of ClassDeclaration.
  2. Let className be the sole element of the BoundNames of ClassDeclaration.
  3. If className is "*default*", then
    1. Let env be the running execution context's LexicalEnvironment.
    2. Perform ? InitializeBoundName("*default*", value, env).
  4. Return empty.
ExportDeclaration : export default AssignmentExpression ;
  1. If IsAnonymousFunctionDefinition(AssignmentExpression) is true, then
    1. Let value be ? NamedEvaluation of AssignmentExpression with argument "default".
  2. Else,
    1. Let rhs be ? Evaluation of AssignmentExpression.
    2. Let value be ? GetValue(rhs).
  3. Let env be the running execution context's LexicalEnvironment.
  4. Perform ? InitializeBoundName("*default*", value, env).
  5. Return empty.

17 Error Handling and Language Extensions

An implementation must report most errors at the time the relevant ECMAScript language construct is evaluated. An early error is an error that can be detected and reported prior to the evaluation of any construct in the Script containing the error. The presence of an early error prevents the evaluation of the construct. An implementation must report early errors in a Script as part of parsing that Script in ParseScript. Early errors in a Module are reported at the point when the Module would be evaluated and the Module is never initialized. Early errors in eval code are reported at the time eval is called and prevent evaluation of the eval code. All errors that are not early errors are runtime errors.

An implementation must report as an early error any occurrence of a condition that is listed in a “Static Semantics: Early Errors” subclause of this specification.

An implementation shall not treat other kinds of errors as early errors even if the compiler can prove that a construct cannot execute without error under any circumstances. An implementation may issue an early warning in such a case, but it should not report the error until the relevant construct is actually executed.

An implementation shall report all errors as specified, except for the following:

17.1 Forbidden Extensions

An implementation must not extend this specification in the following ways:

18 ECMAScript Standard Built-in Objects

There are certain built-in objects available whenever an ECMAScript Script or Module begins execution. One, the global object, is part of the global environment of the executing program. Others are accessible as initial properties of the global object or indirectly as properties of accessible built-in objects.

Unless specified otherwise, a built-in object that is callable as a function is a built-in function object with the characteristics described in 10.3. Unless specified otherwise, the [[Extensible]] internal slot of a built-in object initially has the value true. Every built-in function object has a [[Realm]] internal slot whose value is the Realm Record of the realm for which the object was initially created.

Many built-in objects are functions: they can be invoked with arguments. Some of them furthermore are constructors: they are functions intended for use with the new operator. For each built-in function, this specification describes the arguments required by that function and the properties of that function object. For each built-in constructor, this specification furthermore describes properties of the prototype object of that constructor and properties of specific object instances returned by a new expression that invokes that constructor.

Unless otherwise specified in the description of a particular function, if a built-in function or constructor is given fewer arguments than the function is specified to require, the function or constructor shall behave exactly as if it had been given sufficient additional arguments, each such argument being the undefined value. Such missing arguments are considered to be “not present” and may be identified in that manner by specification algorithms. In the description of a particular function, the terms “this value” and “NewTarget” have the meanings given in 10.3.

Unless otherwise specified in the description of a particular function, if a built-in function or constructor described is given more arguments than the function is specified to allow, the extra arguments are evaluated by the call and then ignored by the function. However, an implementation may define implementation specific behaviour relating to such arguments as long as the behaviour is not the throwing of a TypeError exception that is predicated simply on the presence of an extra argument.

Note 1

Implementations that add additional capabilities to the set of built-in functions are encouraged to do so by adding new functions rather than adding new parameters to existing functions.

Unless otherwise specified every built-in function and every built-in constructor has the Function prototype object, which is the initial value of the expression Function.prototype (20.2.3), as the value of its [[Prototype]] internal slot.

Unless otherwise specified every built-in prototype object has the Object prototype object, which is the initial value of the expression Object.prototype (20.1.3), as the value of its [[Prototype]] internal slot, except the Object prototype object itself.

If this specification defines a built-in constructor's behaviour via algorithm steps, then that is its behaviour for the purposes of both [[Call]] and [[Construct]]. If such an algorithm needs to distinguish the two cases, it checks whether NewTarget is undefined, which indicates a [[Call]] invocation.

Built-in function objects that are not identified as constructors do not implement the [[Construct]] internal method unless otherwise specified in the description of a particular function.

Built-in function objects that are not constructors do not have a "prototype" property unless otherwise specified in the description of a particular function.

Each built-in function defined in this specification is created by calling the CreateBuiltinFunction abstract operation (10.3.4). The values of the length and name parameters are the initial values of the "length" and "name" properties as discussed below. The values of the prefix parameter are similarly discussed below.

Every built-in function object, including constructors, has a "length" property whose value is a non-negative integral Number. Unless otherwise specified, this value is the number of required parameters shown in the subclause heading for the function description. Optional parameters and rest parameters are not included in the parameter count.

Note 2

For example, the function object that is the initial value of the "map" property of the Array prototype object is described under the subclause heading «Array.prototype.map (callback [ , thisArg])» which shows the two named arguments callback and thisArg, the latter being optional; therefore the value of the "length" property of that function object is 1𝔽.

Unless otherwise specified, the "length" property of a built-in function object has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

Every built-in function object, including constructors, has a "name" property whose value is a String. Unless otherwise specified, this value is the name that is given to the function in this specification. Functions that are identified as anonymous functions use the empty String as the value of the "name" property. For functions that are specified as properties of objects, the name value is the property name string used to access the function. Functions that are specified as get or set accessor functions of built-in properties have "get" or "set" (respectively) passed to the prefix parameter when calling CreateBuiltinFunction.

The value of the "name" property is explicitly specified for each built-in functions whose property key is a Symbol value. If such an explicitly specified value starts with the prefix "get " or "set " and the function for which it is specified is a get or set accessor function of a built-in property, the value without the prefix is passed to the name parameter, and the value "get" or "set" (respectively) is passed to the prefix parameter when calling CreateBuiltinFunction.

Unless otherwise specified, the "name" property of a built-in function object has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

Every other data property described in clauses 19 through 28 and in Annex B.2 has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true } unless otherwise specified.

Every accessor property described in clauses 19 through 28 and in Annex B.2 has the attributes { [[Enumerable]]: false, [[Configurable]]: true } unless otherwise specified. If only a get accessor function is described, the set accessor function is the default value, undefined. If only a set accessor is described the get accessor is the default value, undefined.

19 The Global Object

The global object:

19.1 Value Properties of the Global Object

19.1.1 globalThis

The initial value of the "globalThis" property of the global object in a Realm Record realm is realm.[[GlobalEnv]].[[GlobalThisValue]].

This property has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }.

19.1.2 Infinity

The value of Infinity is +∞𝔽 (see 6.1.6.1). This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

19.1.3 NaN

The value of NaN is NaN (see 6.1.6.1). This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

19.1.4 undefined

The value of undefined is undefined (see 6.1.1). This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

19.2 Function Properties of the Global Object

19.2.1 eval ( x )

This function is the %eval% intrinsic object.

It performs the following steps when called:

  1. Return ? PerformEval(x, false, false).

19.2.1.1 PerformEval ( x, strictCaller, direct )

The abstract operation PerformEval takes arguments x (an ECMAScript language value), strictCaller (a Boolean), and direct (a Boolean) and returns either a normal completion containing an ECMAScript language value or a throw completion. It performs the following steps when called:

  1. Assert: If direct is false, then strictCaller is also false.
  2. If x is not a String, return x.
  3. Let evalRealm be the current Realm Record.
  4. NOTE: In the case of a direct eval, evalRealm is the realm of both the caller of eval and of the eval function itself.
  5. Perform ? HostEnsureCanCompileStrings(evalRealm, « », x, direct).
  6. Let inFunction be false.
  7. Let inMethod be false.
  8. Let inDerivedConstructor be false.
  9. Let inClassFieldInitializer be false.
  10. If direct is true, then
    1. Let thisEnvRec be GetThisEnvironment().
    2. If thisEnvRec is a Function Environment Record, then
      1. Let F be thisEnvRec.[[FunctionObject]].
      2. Set inFunction to true.
      3. Set inMethod to thisEnvRec.HasSuperBinding().
      4. If F.[[ConstructorKind]] is derived, set inDerivedConstructor to true.
      5. Let classFieldInitializerName be F.[[ClassFieldInitializerName]].
      6. If classFieldInitializerName is not empty, set inClassFieldInitializer to true.
  11. Perform the following substeps in an implementation-defined order, possibly interleaving parsing and error detection:
    1. Let script be ParseText(x, Script).
    2. If script is a List of errors, throw a SyntaxError exception.
    3. If script Contains ScriptBody is false, return undefined.
    4. Let body be the ScriptBody of script.
    5. If inFunction is false and body Contains NewTarget, throw a SyntaxError exception.
    6. If inMethod is false and body Contains SuperProperty, throw a SyntaxError exception.
    7. If inDerivedConstructor is false and body Contains SuperCall, throw a SyntaxError exception.
    8. If inClassFieldInitializer is true and ContainsArguments of body is true, throw a SyntaxError exception.
  12. If strictCaller is true, let strictEval be true.
  13. Else, let strictEval be ScriptIsStrict of script.
  14. Let runningContext be the running execution context.
  15. NOTE: If direct is true, runningContext will be the execution context that performed the direct eval. If direct is false, runningContext will be the execution context for the invocation of the eval function.
  16. If direct is true, then
    1. Let lexEnv be NewDeclarativeEnvironment(runningContext's LexicalEnvironment).
    2. Let varEnv be runningContext's VariableEnvironment.
    3. Let privateEnv be runningContext's PrivateEnvironment.
  17. Else,
    1. Let lexEnv be NewDeclarativeEnvironment(evalRealm.[[GlobalEnv]]).
    2. Let varEnv be evalRealm.[[GlobalEnv]].
    3. Let privateEnv be null.
  18. If strictEval is true, set varEnv to lexEnv.
  19. If runningContext is not already suspended, suspend runningContext.
  20. Let evalContext be a new ECMAScript code execution context.
  21. Set evalContext's Function to null.
  22. Set evalContext's Realm to evalRealm.
  23. Set evalContext's ScriptOrModule to runningContext's ScriptOrModule.
  24. Set evalContext's VariableEnvironment to varEnv.
  25. Set evalContext's LexicalEnvironment to lexEnv.
  26. Set evalContext's PrivateEnvironment to privateEnv.
  27. Push evalContext onto the execution context stack; evalContext is now the running execution context.
  28. Let result be Completion(EvalDeclarationInstantiation(body, varEnv, lexEnv, privateEnv, strictEval)).
  29. If result is a normal completion, then
    1. Set result to Completion(Evaluation of body).
  30. If result is a normal completion and result.[[Value]] is empty, then
    1. Set result to NormalCompletion(undefined).
  31. Suspend evalContext and remove it from the execution context stack.
  32. Resume the context that is now on the top of the execution context stack as the running execution context.
  33. Return ? result.
Note

The eval code cannot instantiate variable or function bindings in the variable environment of the calling context that invoked the eval if either the code of the calling context or the eval code is strict mode code. Instead such bindings are instantiated in a new VariableEnvironment that is only accessible to the eval code. Bindings introduced by let, const, or class declarations are always instantiated in a new LexicalEnvironment.

19.2.1.2 HostEnsureCanCompileStrings ( calleeRealm, parameterStrings, bodyString, direct )

The host-defined abstract operation HostEnsureCanCompileStrings takes arguments calleeRealm (a Realm Record), parameterStrings (a List of Strings), bodyString (a String), and direct (a Boolean) and returns either a normal completion containing unused or a throw completion. It allows host environments to block certain ECMAScript functions which allow developers to interpret and evaluate strings as ECMAScript code.

parameterStrings represents the strings that, when using one of the function constructors, will be concatenated together to build the parameters list. bodyString represents the function body or the string passed to an eval call. direct signifies whether the evaluation is a direct eval.

The default implementation of HostEnsureCanCompileStrings is to return NormalCompletion(unused).

19.2.1.3 EvalDeclarationInstantiation ( body, varEnv, lexEnv, privateEnv, strict )

The abstract operation EvalDeclarationInstantiation takes arguments body (a ScriptBody Parse Node), varEnv (an Environment Record), lexEnv (a Declarative Environment Record), privateEnv (a PrivateEnvironment Record or null), and strict (a Boolean) and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:

  1. Let varNames be the VarDeclaredNames of body.
  2. Let varDeclarations be the VarScopedDeclarations of body.
  3. If strict is false, then
    1. If varEnv is a Global Environment Record, then
      1. For each element name of varNames, do
        1. If HasLexicalDeclaration(varEnv, name) is true, throw a SyntaxError exception.
        2. NOTE: eval will not create a global var declaration that would be shadowed by a global lexical declaration.
    2. Let thisEnv be lexEnv.
    3. Assert: The following loop will terminate.
    4. Repeat, while thisEnv and varEnv are not the same Environment Record,
      1. If thisEnv is not an Object Environment Record, then
        1. NOTE: The environment of with statements cannot contain any lexical declaration so it doesn't need to be checked for var/let hoisting conflicts.
        2. For each element name of varNames, do
          1. If ! thisEnv.HasBinding(name) is true, then
            1. Throw a SyntaxError exception.
            2. NOTE: Annex B.3.4 defines alternate semantics for the above step.
          2. NOTE: A direct eval will not hoist var declaration over a like-named lexical declaration.
      2. Set thisEnv to thisEnv.[[OuterEnv]].
  4. Let privateIdentifiers be a new empty List.
  5. Let pointer be privateEnv.
  6. Repeat, while pointer is not null,
    1. For each Private Name binding of pointer.[[Names]], do
      1. If privateIdentifiers does not contain binding.[[Description]], append binding.[[Description]] to privateIdentifiers.
    2. Set pointer to pointer.[[OuterPrivateEnvironment]].
  7. If AllPrivateIdentifiersValid of body with argument privateIdentifiers is false, throw a SyntaxError exception.
  8. Let functionsToInitialize be a new empty List.
  9. Let declaredFunctionNames be a new empty List.
  10. For each element d of varDeclarations, in reverse List order, do
    1. If d is not either a VariableDeclaration, a ForBinding, or a BindingIdentifier, then
      1. Assert: d is either a FunctionDeclaration, a GeneratorDeclaration, an AsyncFunctionDeclaration, or an AsyncGeneratorDeclaration.
      2. NOTE: If there are multiple function declarations for the same name, the last declaration is used.
      3. Let fn be the sole element of the BoundNames of d.
      4. If declaredFunctionNames does not contain fn, then
        1. If varEnv is a Global Environment Record, then
          1. Let fnDefinable be ? CanDeclareGlobalFunction(varEnv, fn).
          2. If fnDefinable is false, throw a TypeError exception.
        2. Append fn to declaredFunctionNames.
        3. Insert d as the first element of functionsToInitialize.
  11. Let declaredVarNames be a new empty List.
  12. For each element d of varDeclarations, do
    1. If d is either a VariableDeclaration, a ForBinding, or a BindingIdentifier, then
      1. For each String vn of the BoundNames of d, do
        1. If declaredFunctionNames does not contain vn, then
          1. If varEnv is a Global Environment Record, then
            1. Let vnDefinable be ? CanDeclareGlobalVar(varEnv, vn).
            2. If vnDefinable is false, throw a TypeError exception.
          2. If declaredVarNames does not contain vn, then
            1. Append vn to declaredVarNames.
  13. NOTE: Annex B.3.2.3 adds additional steps at this point.
  14. NOTE: No abnormal terminations occur after this algorithm step unless varEnv is a Global Environment Record and the global object is a Proxy exotic object.
  15. Let lexDeclarations be the LexicallyScopedDeclarations of body.
  16. For each element d of lexDeclarations, do
    1. NOTE: Lexically declared names are only instantiated here but not initialized.
    2. For each element dn of the BoundNames of d, do
      1. If IsConstantDeclaration of d is true, then
        1. Perform ? lexEnv.CreateImmutableBinding(dn, true).
      2. Else,
        1. Perform ? lexEnv.CreateMutableBinding(dn, false).
  17. For each Parse Node f of functionsToInitialize, do
    1. Let fn be the sole element of the BoundNames of f.
    2. Let fo be InstantiateFunctionObject of f with arguments lexEnv and privateEnv.
    3. If varEnv is a Global Environment Record, then
      1. Perform ? CreateGlobalFunctionBinding(varEnv, fn, fo, true).
    4. Else,
      1. Let bindingExists be ! varEnv.HasBinding(fn).
      2. If bindingExists is false, then
        1. NOTE: The following invocation cannot return an abrupt completion because of the validation preceding step 14.
        2. Perform ! varEnv.CreateMutableBinding(fn, true).
        3. Perform ! varEnv.InitializeBinding(fn, fo).
      3. Else,
        1. Perform ! varEnv.SetMutableBinding(fn, fo, false).
  18. For each String vn of declaredVarNames, do
    1. If varEnv is a Global Environment Record, then
      1. Perform ? CreateGlobalVarBinding(varEnv, vn, true).
    2. Else,
      1. Let bindingExists be ! varEnv.HasBinding(vn).
      2. If bindingExists is false, then
        1. NOTE: The following invocation cannot return an abrupt completion because of the validation preceding step 14.
        2. Perform ! varEnv.CreateMutableBinding(vn, true).
        3. Perform ! varEnv.InitializeBinding(vn, undefined).
  19. Return unused.
Note

An alternative version of this algorithm is described in B.3.4.

19.2.2 isFinite ( number )

This function is the %isFinite% intrinsic object.

It performs the following steps when called:

  1. Let num be ? ToNumber(number).
  2. If num is not finite, return false.
  3. Otherwise, return true.

19.2.3 isNaN ( number )

This function is the %isNaN% intrinsic object.

It performs the following steps when called:

  1. Let num be ? ToNumber(number).
  2. If num is NaN, return true.
  3. Otherwise, return false.
Note

A reliable way for ECMAScript code to test if a value X is NaN is an expression of the form X !== X. The result will be true if and only if X is NaN.

19.2.4 parseFloat ( string )

This function produces a Number value dictated by interpretation of the contents of the string argument as a decimal literal.

It is the %parseFloat% intrinsic object.

It performs the following steps when called:

  1. Let inputString be ? ToString(string).
  2. Let trimmedString be ! TrimString(inputString, start).
  3. Let trimmed be StringToCodePoints(trimmedString).
  4. Let trimmedPrefix be the longest prefix of trimmed that satisfies the syntax of a StrDecimalLiteral, which might be trimmed itself. If there is no such prefix, return NaN.
  5. Let parsedNumber be ParseText(trimmedPrefix, StrDecimalLiteral).
  6. Assert: parsedNumber is a Parse Node.
  7. Return the StringNumericValue of parsedNumber.
Note

This function may interpret only a leading portion of string as a Number value; it ignores any code units that cannot be interpreted as part of the notation of a decimal literal, and no indication is given that any such code units were ignored.

19.2.5 parseInt ( string, radix )

This function produces an integral Number dictated by interpretation of the contents of string according to the specified radix. Leading white space in string is ignored. If radix coerces to 0 (such as when it is undefined), it is assumed to be 10 except when the number representation begins with "0x" or "0X", in which case it is assumed to be 16. If radix is 16, the number representation may optionally begin with "0x" or "0X".

It is the %parseInt% intrinsic object.

It performs the following steps when called:

  1. Let inputString be ? ToString(string).
  2. Let S be ! TrimString(inputString, start).
  3. Let sign be 1.
  4. If S is not empty and the first code unit of S is the code unit 0x002D (HYPHEN-MINUS), set sign to -1.
  5. If S is not empty and the first code unit of S is either the code unit 0x002B (PLUS SIGN) or the code unit 0x002D (HYPHEN-MINUS), set S to the substring of S from index 1.
  6. Let R be (? ToInt32(radix)).
  7. Let stripPrefix be true.
  8. If R ≠ 0, then
    1. If R < 2 or R > 36, return NaN.
    2. If R ≠ 16, set stripPrefix to false.
  9. Else,
    1. Set R to 10.
  10. If stripPrefix is true, then
    1. If the length of S is at least 2 and the first two code units of S are either "0x" or "0X", then
      1. Set S to the substring of S from index 2.
      2. Set R to 16.
  11. If S contains a code unit that is not a radix-R digit, let end be the index within S of the first such code unit; otherwise let end be the length of S.
  12. Let Z be the substring of S from 0 to end.
  13. If Z is empty, return NaN.
  14. Let mathInt be the integer value that is represented by Z in radix-R notation, using the letters A through Z and a through z for digits with values 10 through 35. (However, if R = 10 and Z contains more than 20 significant digits, every significant digit after the 20th may be replaced by a 0 digit, at the option of the implementation; and if R is not one of 2, 4, 8, 10, 16, or 32, then mathInt may be an implementation-approximated integer representing the integer value denoted by Z in radix-R notation.)
  15. If mathInt = 0, then
    1. If sign = -1, return -0𝔽.
    2. Return +0𝔽.
  16. Return 𝔽(sign × mathInt).
Note

This function may interpret only a leading portion of string as an integer value; it ignores any code units that cannot be interpreted as part of the notation of an integer, and no indication is given that any such code units were ignored.

19.2.6 URI Handling Functions

Uniform Resource Identifiers, or URIs, are Strings that identify resources (e.g. web pages or files) and transport protocols by which to access them (e.g. HTTP or FTP) on the Internet. The ECMAScript language itself does not provide any support for using URIs except for functions that encode and decode URIs as described in this section. encodeURI and decodeURI are intended to work with complete URIs; they assume that any reserved characters are intended to have special meaning (e.g., as delimiters) and so are not encoded. encodeURIComponent and decodeURIComponent are intended to work with the individual components of a URI; they assume that any reserved characters represent text and must be encoded to avoid special meaning when the component is part of a complete URI.

Note 1

The set of reserved characters is based upon RFC 2396 and does not reflect changes introduced by the more recent RFC 3986.

Note 2

Many implementations of ECMAScript provide additional functions and methods that manipulate web pages; these functions are beyond the scope of this standard.

19.2.6.1 decodeURI ( encodedURI )

This function computes a new version of a URI in which each escape sequence and UTF-8 encoding of the sort that might be introduced by the encodeURI function is replaced with the UTF-16 encoding of the code point that it represents. Escape sequences that could not have been introduced by encodeURI are not replaced.

It is the %decodeURI% intrinsic object.

It performs the following steps when called:

  1. Let uriString be ? ToString(encodedURI).
  2. Let preserveEscapeSet be ";/?:@&=+$,#".
  3. Return ? Decode(uriString, preserveEscapeSet).

19.2.6.2 decodeURIComponent ( encodedURIComponent )

This function computes a new version of a URI in which each escape sequence and UTF-8 encoding of the sort that might be introduced by the encodeURIComponent function is replaced with the UTF-16 encoding of the code point that it represents.

It is the %decodeURIComponent% intrinsic object.

It performs the following steps when called:

  1. Let componentString be ? ToString(encodedURIComponent).
  2. Let preserveEscapeSet be the empty String.
  3. Return ? Decode(componentString, preserveEscapeSet).

19.2.6.3 encodeURI ( uri )

This function computes a new version of a UTF-16 encoded (6.1.4) URI in which each instance of certain code points is replaced by one, two, three, or four escape sequences representing the UTF-8 encoding of the code point.

It is the %encodeURI% intrinsic object.

It performs the following steps when called:

  1. Let uriString be ? ToString(uri).
  2. Let extraUnescaped be ";/?:@&=+$,#".
  3. Return ? Encode(uriString, extraUnescaped).

19.2.6.4 encodeURIComponent ( uriComponent )

This function computes a new version of a UTF-16 encoded (6.1.4) URI in which each instance of certain code points is replaced by one, two, three, or four escape sequences representing the UTF-8 encoding of the code point.

It is the %encodeURIComponent% intrinsic object.

It performs the following steps when called:

  1. Let componentString be ? ToString(uriComponent).
  2. Let extraUnescaped be the empty String.
  3. Return ? Encode(componentString, extraUnescaped).

19.2.6.5 Encode ( string, extraUnescaped )

The abstract operation Encode takes arguments string (a String) and extraUnescaped (a String) and returns either a normal completion containing a String or a throw completion. It performs URI encoding and escaping, interpreting string as a sequence of UTF-16 encoded code points as described in 6.1.4. If a character is identified as unreserved in RFC 2396 or appears in extraUnescaped, it is not escaped. It performs the following steps when called:

  1. Let len be the length of string.
  2. Let R be the empty String.
  3. Let alwaysUnescaped be the string-concatenation of the ASCII word characters and "-.!~*'()".
  4. Let unescapedSet be the string-concatenation of alwaysUnescaped and extraUnescaped.
  5. Let k be 0.
  6. Repeat, while k < len,
    1. Let C be the code unit at index k within string.
    2. If unescapedSet contains C, then
      1. Set k to k + 1.
      2. Set R to the string-concatenation of R and C.
    3. Else,
      1. Let cp be CodePointAt(string, k).
      2. If cp.[[IsUnpairedSurrogate]] is true, throw a URIError exception.
      3. Set k to k + cp.[[CodeUnitCount]].
      4. Let Octets be the List of octets resulting by applying the UTF-8 transformation to cp.[[CodePoint]].
      5. For each element octet of Octets, do
        1. Let hex be the String representation of octet, formatted as an uppercase hexadecimal number.
        2. Set R to the string-concatenation of R, "%", and StringPad(hex, 2, "0", start).
  7. Return R.
Note

Because percent-encoding is used to represent individual octets, a single code point may be expressed as multiple consecutive escape sequences (one for each of its 8-bit UTF-8 code units).

19.2.6.6 Decode ( string, preserveEscapeSet )

The abstract operation Decode takes arguments string (a String) and preserveEscapeSet (a String) and returns either a normal completion containing a String or a throw completion. It performs URI unescaping and decoding, preserving any escape sequences that correspond to Basic Latin characters in preserveEscapeSet. It performs the following steps when called:

  1. Let len be the length of string.
  2. Let R be the empty String.
  3. Let k be 0.
  4. Repeat, while k < len,
    1. Let C be the code unit at index k within string.
    2. Let S be C.
    3. If C is the code unit 0x0025 (PERCENT SIGN), then
      1. If k + 3 > len, throw a URIError exception.
      2. Let escape be the substring of string from k to k + 3.
      3. Let B be ParseHexOctet(string, k + 1).
      4. If B is not an integer, throw a URIError exception.
      5. Set k to k + 2.
      6. Let n be the number of leading 1 bits in B.
      7. If n = 0, then
        1. Let asciiChar be the code unit whose numeric value is B.
        2. If preserveEscapeSet contains asciiChar, set S to escape; otherwise set S to asciiChar.
      8. Else,
        1. If n = 1 or n > 4, throw a URIError exception.
        2. Let Octets be « B ».
        3. Let j be 1.
        4. Repeat, while j < n,
          1. Set k to k + 1.
          2. If k + 3 > len, throw a URIError exception.
          3. If the code unit at index k within string is not the code unit 0x0025 (PERCENT SIGN), throw a URIError exception.
          4. Let continuationByte be ParseHexOctet(string, k + 1).
          5. If continuationByte is not an integer, throw a URIError exception.
          6. Append continuationByte to Octets.
          7. Set k to k + 2.
          8. Set j to j + 1.
        5. Assert: The length of Octets is n.
        6. If Octets does not contain a valid UTF-8 encoding of a Unicode code point, throw a URIError exception.
        7. Let V be the code point obtained by applying the UTF-8 transformation to Octets, that is, from a List of octets into a 21-bit value.
        8. Set S to UTF16EncodeCodePoint(V).
    4. Set R to the string-concatenation of R and S.
    5. Set k to k + 1.
  5. Return R.
Note

RFC 3629 prohibits the decoding of invalid UTF-8 octet sequences. For example, the invalid sequence 0xC0 0x80 must not decode into the code unit 0x0000. Implementations of the Decode algorithm are required to throw a URIError when encountering such invalid sequences.

19.2.6.7 ParseHexOctet ( string, position )

The abstract operation ParseHexOctet takes arguments string (a String) and position (a non-negative integer) and returns either a non-negative integer or a non-empty List of SyntaxError objects. It parses a sequence of two hexadecimal characters at the specified position in string into an unsigned 8-bit integer. It performs the following steps when called:

  1. Let len be the length of string.
  2. Assert: position + 2 ≤ len.
  3. Let hexDigits be the substring of string from position to position + 2.
  4. Let parseResult be ParseText(hexDigits, HexDigits[~Sep]).
  5. If parseResult is not a Parse Node, return parseResult.
  6. Let n be the MV of parseResult.
  7. Assert: n is in the inclusive interval from 0 to 255.
  8. Return n.

19.3 Constructor Properties of the Global Object

19.3.1 AggregateError ( . . . )

See 20.5.7.1.

19.3.2 Array ( . . . )

See 23.1.1.

19.3.3 ArrayBuffer ( . . . )

See 25.1.4.

19.3.4 BigInt ( . . . )

See 21.2.1.

19.3.5 BigInt64Array ( . . . )

See 23.2.5.

19.3.6 BigUint64Array ( . . . )

See 23.2.5.

19.3.7 Boolean ( . . . )

See 20.3.1.

19.3.8 DataView ( . . . )

See 25.3.2.

19.3.9 Date ( . . . )

See 21.4.2.

19.3.10 Error ( . . . )

See 20.5.1.

19.3.11 EvalError ( . . . )

See 20.5.5.1.

19.3.12 FinalizationRegistry ( . . . )

See 26.2.1.

19.3.13 Float16Array ( . . . )

See 23.2.5.

19.3.14 Float32Array ( . . . )

See 23.2.5.

19.3.15 Float64Array ( . . . )

See 23.2.5.

19.3.16 Function ( . . . )

See 20.2.1.

19.3.17 Int8Array ( . . . )

See 23.2.5.

19.3.18 Int16Array ( . . . )

See 23.2.5.

19.3.19 Int32Array ( . . . )

See 23.2.5.

19.3.20 Iterator ( . . . )

See 27.1.3.1.

19.3.21 Map ( . . . )

See 24.1.1.

19.3.22 Number ( . . . )

See 21.1.1.

19.3.23 Object ( . . . )

See 20.1.1.

19.3.24 Promise ( . . . )

See 27.2.3.

19.3.25 Proxy ( . . . )

See 28.2.1.

19.3.26 RangeError ( . . . )

See 20.5.5.2.

19.3.27 ReferenceError ( . . . )

See 20.5.5.3.

19.3.28 RegExp ( . . . )

See 22.2.4.

19.3.29 Set ( . . . )

See 24.2.2.

19.3.30 SharedArrayBuffer ( . . . )

See 25.2.3.

19.3.31 String ( . . . )

See 22.1.1.

19.3.32 Symbol ( . . . )

See 20.4.1.

19.3.33 SyntaxError ( . . . )

See 20.5.5.4.

19.3.34 TypeError ( . . . )

See 20.5.5.5.

19.3.35 Uint8Array ( . . . )

See 23.2.5.

19.3.36 Uint8ClampedArray ( . . . )

See 23.2.5.

19.3.37 Uint16Array ( . . . )

See 23.2.5.

19.3.38 Uint32Array ( . . . )

See 23.2.5.

19.3.39 URIError ( . . . )

See 20.5.5.6.

19.3.40 WeakMap ( . . . )

See 24.3.1.

19.3.41 WeakRef ( . . . )

See 26.1.1.

19.3.42 WeakSet ( . . . )

See 24.4.

19.4 Other Properties of the Global Object

19.4.1 Atomics

See 25.4.

19.4.2 JSON

See 25.5.

19.4.3 Math

See 21.3.

19.4.4 Reflect

See 28.1.

20 Fundamental Objects

20.1 Object Objects

20.1.1 The Object Constructor

The Object constructor:

  • is %Object%.
  • is the initial value of the "Object" property of the global object.
  • creates a new ordinary object when called as a constructor.
  • performs a type conversion when called as a function rather than as a constructor.
  • may be used as the value of an extends clause of a class definition.

20.1.1.1 Object ( [ value ] )

This function performs the following steps when called:

  1. If NewTarget is neither undefined nor the active function object, then
    1. Return ? OrdinaryCreateFromConstructor(NewTarget, "%Object.prototype%").
  2. If value is either undefined or null, return OrdinaryObjectCreate(%Object.prototype%).
  3. Return ! ToObject(value).

20.1.2 Properties of the Object Constructor

The Object constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has a "length" property whose value is 1𝔽.
  • has the following additional properties:

20.1.2.1 Object.assign ( target, ...sources )

This function copies the values of all of the enumerable own properties from one or more source objects to a target object.

It performs the following steps when called:

  1. Let to be ? ToObject(target).
  2. If only one argument was passed, return to.
  3. For each element nextSource of sources, do
    1. If nextSource is neither undefined nor null, then
      1. Let from be ! ToObject(nextSource).
      2. Let keys be ? from.[[OwnPropertyKeys]]().
      3. For each element nextKey of keys, do
        1. Let desc be ? from.[[GetOwnProperty]](nextKey).
        2. If desc is not undefined and desc.[[Enumerable]] is true, then
          1. Let propValue be ? Get(from, nextKey).
          2. Perform ? Set(to, nextKey, propValue, true).
  4. Return to.

The "length" property of this function is 2𝔽.

20.1.2.2 Object.create ( O, Properties )

This function creates a new object with a specified prototype.

It performs the following steps when called:

  1. If O is not an Object and O is not null, throw a TypeError exception.
  2. Let obj be OrdinaryObjectCreate(O).
  3. If Properties is not undefined, then
    1. Return ? ObjectDefineProperties(obj, Properties).
  4. Return obj.

20.1.2.3 Object.defineProperties ( O, Properties )

This function adds own properties and/or updates the attributes of existing own properties of an object.

It performs the following steps when called:

  1. If O is not an Object, throw a TypeError exception.
  2. Return ? ObjectDefineProperties(O, Properties).

20.1.2.3.1 ObjectDefineProperties ( O, Properties )

The abstract operation ObjectDefineProperties takes arguments O (an Object) and Properties (an ECMAScript language value) and returns either a normal completion containing an Object or a throw completion. It performs the following steps when called:

  1. Let props be ? ToObject(Properties).
  2. Let keys be ? props.[[OwnPropertyKeys]]().
  3. Let descriptors be a new empty List.
  4. For each element nextKey of keys, do
    1. Let propDesc be ? props.[[GetOwnProperty]](nextKey).
    2. If propDesc is not undefined and propDesc.[[Enumerable]] is true, then
      1. Let descObj be ? Get(props, nextKey).
      2. Let desc be ? ToPropertyDescriptor(descObj).
      3. Append the Record { [[Key]]: nextKey, [[Descriptor]]: desc } to descriptors.
  5. For each element property of descriptors, do
    1. Perform ? DefinePropertyOrThrow(O, property.[[Key]], property.[[Descriptor]]).
  6. Return O.

20.1.2.4 Object.defineProperty ( O, P, Attributes )

This function adds an own property and/or updates the attributes of an existing own property of an object.

It performs the following steps when called:

  1. If O is not an Object, throw a TypeError exception.
  2. Let key be ? ToPropertyKey(P).
  3. Let desc be ? ToPropertyDescriptor(Attributes).
  4. Perform ? DefinePropertyOrThrow(O, key, desc).
  5. Return O.

20.1.2.5 Object.entries ( O )

This function performs the following steps when called:

  1. Let obj be ? ToObject(O).
  2. Let entryList be ? EnumerableOwnProperties(obj, key+value).
  3. Return CreateArrayFromList(entryList).

20.1.2.6 Object.freeze ( O )

This function performs the following steps when called:

  1. If O is not an Object, return O.
  2. Let status be ? SetIntegrityLevel(O, frozen).
  3. If status is false, throw a TypeError exception.
  4. Return O.

20.1.2.7 Object.fromEntries ( iterable )

This function performs the following steps when called:

  1. Perform ? RequireObjectCoercible(iterable).
  2. Let obj be OrdinaryObjectCreate(%Object.prototype%).
  3. Assert: obj is an extensible ordinary object with no own properties.
  4. Let closure be a new Abstract Closure with parameters (key, value) that captures obj and performs the following steps when called:
    1. Let propertyKey be ? ToPropertyKey(key).
    2. Perform ! CreateDataPropertyOrThrow(obj, propertyKey, value).
    3. Return NormalCompletion(undefined).
  5. Let adder be CreateBuiltinFunction(closure, 2, "", « »).
  6. Return ? AddEntriesFromIterable(obj, iterable, adder).
Note
The function created for adder is never directly accessible to ECMAScript code.

20.1.2.8 Object.getOwnPropertyDescriptor ( O, P )

This function performs the following steps when called:

  1. Let obj be ? ToObject(O).
  2. Let key be ? ToPropertyKey(P).
  3. Let desc be ? obj.[[GetOwnProperty]](key).
  4. Return FromPropertyDescriptor(desc).

20.1.2.9 Object.getOwnPropertyDescriptors ( O )

This function performs the following steps when called:

  1. Let obj be ? ToObject(O).
  2. Let ownKeys be ? obj.[[OwnPropertyKeys]]().
  3. Let descriptors be OrdinaryObjectCreate(%Object.prototype%).
  4. For each element key of ownKeys, do
    1. Let desc be ? obj.[[GetOwnProperty]](key).
    2. Let descriptor be FromPropertyDescriptor(desc).
    3. If descriptor is not undefined, perform ! CreateDataPropertyOrThrow(descriptors, key, descriptor).
  5. Return descriptors.

20.1.2.10 Object.getOwnPropertyNames ( O )

This function performs the following steps when called:

  1. Return CreateArrayFromList(? GetOwnPropertyKeys(O, string)).

20.1.2.11 Object.getOwnPropertySymbols ( O )

This function performs the following steps when called:

  1. Return CreateArrayFromList(? GetOwnPropertyKeys(O, symbol)).

20.1.2.11.1 GetOwnPropertyKeys ( O, type )

The abstract operation GetOwnPropertyKeys takes arguments O (an ECMAScript language value) and type (string or symbol) and returns either a normal completion containing a List of property keys or a throw completion. It performs the following steps when called:

  1. Let obj be ? ToObject(O).
  2. Let keys be ? obj.[[OwnPropertyKeys]]().
  3. Let nameList be a new empty List.
  4. For each element nextKey of keys, do
    1. If nextKey is a Symbol and type is symbol, or if nextKey is a String and type is string, then
      1. Append nextKey to nameList.
  5. Return nameList.

20.1.2.12 Object.getPrototypeOf ( O )

This function performs the following steps when called:

  1. Let obj be ? ToObject(O).
  2. Return ? obj.[[GetPrototypeOf]]().

20.1.2.13 Object.groupBy ( items, callback )

Note

callback should be a function that accepts two arguments. groupBy calls callback once for each element in items, in ascending order, and constructs a new object. Each value returned by callback is coerced to a property key. For each such property key, the result object has a property whose key is that property key and whose value is an array containing all the elements for which the callback return value coerced to that key.

callback is called with two arguments: the value of the element and the index of the element.

The return value of groupBy is an object that does not inherit from %Object.prototype%.

This function performs the following steps when called:

  1. Let groups be ? GroupBy(items, callback, property).
  2. Let obj be OrdinaryObjectCreate(null).
  3. For each Record { [[Key]], [[Elements]] } g of groups, do
    1. Let elements be CreateArrayFromList(g.[[Elements]]).
    2. Perform ! CreateDataPropertyOrThrow(obj, g.[[Key]], elements).
  4. Return obj.

20.1.2.14 Object.hasOwn ( O, P )

This function performs the following steps when called:

  1. Let obj be ? ToObject(O).
  2. Let key be ? ToPropertyKey(P).
  3. Return ? HasOwnProperty(obj, key).

20.1.2.15 Object.is ( value1, value2 )

This function performs the following steps when called:

  1. Return SameValue(value1, value2).

20.1.2.16 Object.isExtensible ( O )

This function performs the following steps when called:

  1. If O is not an Object, return false.
  2. Return ? IsExtensible(O).

20.1.2.17 Object.isFrozen ( O )

This function performs the following steps when called:

  1. If O is not an Object, return true.
  2. Return ? TestIntegrityLevel(O, frozen).

20.1.2.18 Object.isSealed ( O )

This function performs the following steps when called:

  1. If O is not an Object, return true.
  2. Return ? TestIntegrityLevel(O, sealed).

20.1.2.19 Object.keys ( O )

This function performs the following steps when called:

  1. Let obj be ? ToObject(O).
  2. Let keyList be ? EnumerableOwnProperties(obj, key).
  3. Return CreateArrayFromList(keyList).

20.1.2.20 Object.preventExtensions ( O )

This function performs the following steps when called:

  1. If O is not an Object, return O.
  2. Let status be ? O.[[PreventExtensions]]().
  3. If status is false, throw a TypeError exception.
  4. Return O.

20.1.2.21 Object.prototype

The initial value of Object.prototype is the Object prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.1.2.22 Object.seal ( O )

This function performs the following steps when called:

  1. If O is not an Object, return O.
  2. Let status be ? SetIntegrityLevel(O, sealed).
  3. If status is false, throw a TypeError exception.
  4. Return O.

20.1.2.23 Object.setPrototypeOf ( O, proto )

This function performs the following steps when called:

  1. Set O to ? RequireObjectCoercible(O).
  2. If proto is not an Object and proto is not null, throw a TypeError exception.
  3. If O is not an Object, return O.
  4. Let status be ? O.[[SetPrototypeOf]](proto).
  5. If status is false, throw a TypeError exception.
  6. Return O.

20.1.2.24 Object.values ( O )

This function performs the following steps when called:

  1. Let obj be ? ToObject(O).
  2. Let valueList be ? EnumerableOwnProperties(obj, value).
  3. Return CreateArrayFromList(valueList).

20.1.3 Properties of the Object Prototype Object

The Object prototype object:

  • is %Object.prototype%.
  • has an [[Extensible]] internal slot whose value is true.
  • has the internal methods defined for ordinary objects, except for the [[SetPrototypeOf]] method, which is as defined in 10.4.7.1. (Thus, it is an immutable prototype exotic object.)
  • has a [[Prototype]] internal slot whose value is null.

20.1.3.1 Object.prototype.constructor

The initial value of Object.prototype.constructor is %Object%.

20.1.3.2 Object.prototype.hasOwnProperty ( V )

This method performs the following steps when called:

  1. Let P be ? ToPropertyKey(V).
  2. Let O be ? ToObject(this value).
  3. Return ? HasOwnProperty(O, P).
Note

The ordering of steps 1 and 2 is chosen to ensure that any exception that would have been thrown by step 1 in previous editions of this specification will continue to be thrown even if the this value is undefined or null.

20.1.3.3 Object.prototype.isPrototypeOf ( V )

This method performs the following steps when called:

  1. If V is not an Object, return false.
  2. Let O be ? ToObject(this value).
  3. Repeat,
    1. Set V to ? V.[[GetPrototypeOf]]().
    2. If V is null, return false.
    3. If SameValue(O, V) is true, return true.
Note

The ordering of steps 1 and 2 preserves the behaviour specified by previous editions of this specification for the case where V is not an object and the this value is undefined or null.

20.1.3.4 Object.prototype.propertyIsEnumerable ( V )

This method performs the following steps when called:

  1. Let P be ? ToPropertyKey(V).
  2. Let O be ? ToObject(this value).
  3. Let desc be ? O.[[GetOwnProperty]](P).
  4. If desc is undefined, return false.
  5. Return desc.[[Enumerable]].
Note 1

This method does not consider objects in the prototype chain.

Note 2

The ordering of steps 1 and 2 is chosen to ensure that any exception that would have been thrown by step 1 in previous editions of this specification will continue to be thrown even if the this value is undefined or null.

20.1.3.5 Object.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] )

This method performs the following steps when called:

  1. Let O be the this value.
  2. Return ? Invoke(O, "toString").

The optional parameters to this method are not used but are intended to correspond to the parameter pattern used by ECMA-402 toLocaleString methods. Implementations that do not include ECMA-402 support must not use those parameter positions for other purposes.

Note 1

This method provides a generic toLocaleString implementation for objects that have no locale-sensitive toString behaviour. Array, Number, Date, and %TypedArray% provide their own locale-sensitive toLocaleString methods.

Note 2

ECMA-402 intentionally does not provide an alternative to this default implementation.

20.1.3.6 Object.prototype.toString ( )

This method performs the following steps when called:

  1. If the this value is undefined, return "[object Undefined]".
  2. If the this value is null, return "[object Null]".
  3. Let O be ! ToObject(this value).
  4. Let isArray be ? IsArray(O).
  5. If isArray is true, let builtinTag be "Array".
  6. Else if O has a [[ParameterMap]] internal slot, let builtinTag be "Arguments".
  7. Else if O has a [[Call]] internal method, let builtinTag be "Function".
  8. Else if O has an [[ErrorData]] internal slot, let builtinTag be "Error".
  9. Else if O has a [[BooleanData]] internal slot, let builtinTag be "Boolean".
  10. Else if O has a [[NumberData]] internal slot, let builtinTag be "Number".
  11. Else if O has a [[StringData]] internal slot, let builtinTag be "String".
  12. Else if O has a [[DateValue]] internal slot, let builtinTag be "Date".
  13. Else if O has a [[RegExpMatcher]] internal slot, let builtinTag be "RegExp".
  14. Else, let builtinTag be "Object".
  15. Let tag be ? Get(O, %Symbol.toStringTag%).
  16. If tag is not a String, set tag to builtinTag.
  17. Return the string-concatenation of "[object ", tag, and "]".
Note

Historically, this method was occasionally used to access the String value of the [[Class]] internal slot that was used in previous editions of this specification as a nominal type tag for various built-in objects. The above definition of toString preserves compatibility for legacy code that uses toString as a test for those specific kinds of built-in objects. It does not provide a reliable type testing mechanism for other kinds of built-in or program defined objects. In addition, programs can use %Symbol.toStringTag% in ways that will invalidate the reliability of such legacy type tests.

20.1.3.7 Object.prototype.valueOf ( )

This method performs the following steps when called:

  1. Return ? ToObject(this value).

20.1.3.8 Object.prototype.__proto__

Object.prototype.__proto__ is an accessor property with attributes { [[Enumerable]]: false, [[Configurable]]: true }. The [[Get]] and [[Set]] attributes are defined as follows:

20.1.3.8.1 get Object.prototype.__proto__

The value of the [[Get]] attribute is a built-in function that requires no arguments. It performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Return ? O.[[GetPrototypeOf]]().

20.1.3.8.2 set Object.prototype.__proto__

The value of the [[Set]] attribute is a built-in function that takes an argument proto. It performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. If proto is not an Object and proto is not null, return undefined.
  3. If O is not an Object, return undefined.
  4. Let status be ? O.[[SetPrototypeOf]](proto).
  5. If status is false, throw a TypeError exception.
  6. Return undefined.

20.1.3.9 Legacy Object.prototype Accessor Methods

20.1.3.9.1 Object.prototype.__defineGetter__ ( P, getter )

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. If IsCallable(getter) is false, throw a TypeError exception.
  3. Let desc be PropertyDescriptor { [[Get]]: getter, [[Enumerable]]: true, [[Configurable]]: true }.
  4. Let key be ? ToPropertyKey(P).
  5. Perform ? DefinePropertyOrThrow(O, key, desc).
  6. Return undefined.

20.1.3.9.2 Object.prototype.__defineSetter__ ( P, setter )

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. If IsCallable(setter) is false, throw a TypeError exception.
  3. Let desc be PropertyDescriptor { [[Set]]: setter, [[Enumerable]]: true, [[Configurable]]: true }.
  4. Let key be ? ToPropertyKey(P).
  5. Perform ? DefinePropertyOrThrow(O, key, desc).
  6. Return undefined.

20.1.3.9.3 Object.prototype.__lookupGetter__ ( P )

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let key be ? ToPropertyKey(P).
  3. Repeat,
    1. Let desc be ? O.[[GetOwnProperty]](key).
    2. If desc is not undefined, then
      1. If IsAccessorDescriptor(desc) is true, return desc.[[Get]].
      2. Return undefined.
    3. Set O to ? O.[[GetPrototypeOf]]().
    4. If O is null, return undefined.

20.1.3.9.4 Object.prototype.__lookupSetter__ ( P )

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let key be ? ToPropertyKey(P).
  3. Repeat,
    1. Let desc be ? O.[[GetOwnProperty]](key).
    2. If desc is not undefined, then
      1. If IsAccessorDescriptor(desc) is true, return desc.[[Set]].
      2. Return undefined.
    3. Set O to ? O.[[GetPrototypeOf]]().
    4. If O is null, return undefined.

20.1.4 Properties of Object Instances

Object instances have no special properties beyond those inherited from the Object prototype object.

20.2 Function Objects

20.2.1 The Function Constructor

The Function constructor:

  • is %Function%.
  • is the initial value of the "Function" property of the global object.
  • creates and initializes a new function object when called as a function rather than as a constructor. Thus the function call Function(…) is equivalent to the object creation expression new Function(…) with the same arguments.
  • may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified Function behaviour must include a super call to the Function constructor to create and initialize a subclass instance with the internal slots necessary for built-in function behaviour. All ECMAScript syntactic forms for defining function objects create instances of Function. There is no syntactic means to create instances of Function subclasses except for the built-in GeneratorFunction, AsyncFunction, and AsyncGeneratorFunction subclasses.

20.2.1.1 Function ( ...parameterArgs, bodyArg )

The last argument (if any) specifies the body (executable code) of a function; any preceding arguments specify formal parameters.

This function performs the following steps when called:

  1. Let C be the active function object.
  2. If bodyArg is not present, set bodyArg to the empty String.
  3. Return ? CreateDynamicFunction(C, NewTarget, normal, parameterArgs, bodyArg).
Note

It is permissible but not necessary to have one argument for each formal parameter to be specified. For example, all three of the following expressions produce the same result:

new Function("a", "b", "c", "return a+b+c")
new Function("a, b, c", "return a+b+c")
new Function("a,b", "c", "return a+b+c")

20.2.1.1.1 CreateDynamicFunction ( constructor, newTarget, kind, parameterArgs, bodyArg )

The abstract operation CreateDynamicFunction takes arguments constructor (a constructor), newTarget (a constructor or undefined), kind (normal, generator, async, or async-generator), parameterArgs (a List of ECMAScript language values), and bodyArg (an ECMAScript language value) and returns either a normal completion containing an ECMAScript function object or a throw completion. constructor is the constructor function that is performing this action. newTarget is the constructor that new was initially applied to. parameterArgs and bodyArg reflect the argument values that were passed to constructor. It performs the following steps when called:

  1. If newTarget is undefined, set newTarget to constructor.
  2. If kind is normal, then
    1. Let prefix be "function".
    2. Let exprSym be the grammar symbol FunctionExpression.
    3. Let bodySym be the grammar symbol FunctionBody[~Yield, ~Await].
    4. Let parameterSym be the grammar symbol FormalParameters[~Yield, ~Await].
    5. Let fallbackProto be "%Function.prototype%".
  3. Else if kind is generator, then
    1. Let prefix be "function*".
    2. Let exprSym be the grammar symbol GeneratorExpression.
    3. Let bodySym be the grammar symbol GeneratorBody.
    4. Let parameterSym be the grammar symbol FormalParameters[+Yield, ~Await].
    5. Let fallbackProto be "%GeneratorFunction.prototype%".
  4. Else if kind is async, then
    1. Let prefix be "async function".
    2. Let exprSym be the grammar symbol AsyncFunctionExpression.
    3. Let bodySym be the grammar symbol AsyncFunctionBody.
    4. Let parameterSym be the grammar symbol FormalParameters[~Yield, +Await].
    5. Let fallbackProto be "%AsyncFunction.prototype%".
  5. Else,
    1. Assert: kind is async-generator.
    2. Let prefix be "async function*".
    3. Let exprSym be the grammar symbol AsyncGeneratorExpression.
    4. Let bodySym be the grammar symbol AsyncGeneratorBody.
    5. Let parameterSym be the grammar symbol FormalParameters[+Yield, +Await].
    6. Let fallbackProto be "%AsyncGeneratorFunction.prototype%".
  6. Let argCount be the number of elements in parameterArgs.
  7. Let parameterStrings be a new empty List.
  8. For each element arg of parameterArgs, do
    1. Append ? ToString(arg) to parameterStrings.
  9. Let bodyString be ? ToString(bodyArg).
  10. Let currentRealm be the current Realm Record.
  11. Perform ? HostEnsureCanCompileStrings(currentRealm, parameterStrings, bodyString, false).
  12. Let P be the empty String.
  13. If argCount > 0, then
    1. Set P to parameterStrings[0].
    2. Let k be 1.
    3. Repeat, while k < argCount,
      1. Let nextArgString be parameterStrings[k].
      2. Set P to the string-concatenation of P, "," (a comma), and nextArgString.
      3. Set k to k + 1.
  14. Let bodyParseString be the string-concatenation of 0x000A (LINE FEED), bodyString, and 0x000A (LINE FEED).
  15. Let sourceString be the string-concatenation of prefix, " anonymous(", P, 0x000A (LINE FEED), ") {", bodyParseString, and "}".
  16. Let sourceText be StringToCodePoints(sourceString).
  17. Let parameters be ParseText(P, parameterSym).
  18. If parameters is a List of errors, throw a SyntaxError exception.
  19. Let body be ParseText(bodyParseString, bodySym).
  20. If body is a List of errors, throw a SyntaxError exception.
  21. NOTE: The parameters and body are parsed separately to ensure that each is valid alone. For example, new Function("/*", "*/ ) {") does not evaluate to a function.
  22. NOTE: If this step is reached, sourceText must have the syntax of exprSym (although the reverse implication does not hold). The purpose of the next two steps is to enforce any Early Error rules which apply to exprSym directly.
  23. Let expr be ParseText(sourceText, exprSym).
  24. If expr is a List of errors, throw a SyntaxError exception.
  25. Let proto be ? GetPrototypeFromConstructor(newTarget, fallbackProto).
  26. Let env be currentRealm.[[GlobalEnv]].
  27. Let privateEnv be null.
  28. Let F be OrdinaryFunctionCreate(proto, sourceText, parameters, body, non-lexical-this, env, privateEnv).
  29. Perform SetFunctionName(F, "anonymous").
  30. If kind is generator, then
    1. Let prototype be OrdinaryObjectCreate(%GeneratorPrototype%).
    2. Perform ! DefinePropertyOrThrow(F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }).
  31. Else if kind is async-generator, then
    1. Let prototype be OrdinaryObjectCreate(%AsyncGeneratorPrototype%).
    2. Perform ! DefinePropertyOrThrow(F, "prototype", PropertyDescriptor { [[Value]]: prototype, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }).
  32. Else if kind is normal, then
    1. Perform MakeConstructor(F).
  33. NOTE: Functions whose kind is async are not constructable and do not have a [[Construct]] internal method or a "prototype" property.
  34. Return F.
Note

CreateDynamicFunction defines a "prototype" property on any function it creates whose kind is not async to provide for the possibility that the function will be used as a constructor.

20.2.2 Properties of the Function Constructor

The Function constructor:

  • is itself a built-in function object.
  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has a "length" property whose value is 1𝔽.
  • has the following properties:

20.2.2.1 Function.prototype

The value of Function.prototype is the Function prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.2.3 Properties of the Function Prototype Object

The Function prototype object:

  • is %Function.prototype%.
  • is itself a built-in function object.
  • accepts any arguments and returns undefined when invoked.
  • does not have a [[Construct]] internal method; it cannot be used as a constructor with the new operator.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.
  • does not have a "prototype" property.
  • has a "length" property whose value is +0𝔽.
  • has a "name" property whose value is the empty String.
Note

The Function prototype object is specified to be a function object to ensure compatibility with ECMAScript code that was created prior to the ECMAScript 2015 specification.

20.2.3.1 Function.prototype.apply ( thisArg, argArray )

This method performs the following steps when called:

  1. Let func be the this value.
  2. If IsCallable(func) is false, throw a TypeError exception.
  3. If argArray is either undefined or null, then
    1. Perform PrepareForTailCall().
    2. Return ? Call(func, thisArg).
  4. Let argList be ? CreateListFromArrayLike(argArray).
  5. Perform PrepareForTailCall().
  6. Return ? Call(func, thisArg, argList).
Note 1

The thisArg value is passed without modification as the this value. This is a change from Edition 3, where an undefined or null thisArg is replaced with the global object and ToObject is applied to all other values and that result is passed as the this value. Even though the thisArg is passed without modification, non-strict functions still perform these transformations upon entry to the function.

Note 2

If func is either an arrow function or a bound function exotic object, then the thisArg will be ignored by the function [[Call]] in step 6.

20.2.3.2 Function.prototype.bind ( thisArg, ...args )

This method performs the following steps when called:

  1. Let Target be the this value.
  2. If IsCallable(Target) is false, throw a TypeError exception.
  3. Let F be ? BoundFunctionCreate(Target, thisArg, args).
  4. Let L be 0.
  5. Let targetHasLength be ? HasOwnProperty(Target, "length").
  6. If targetHasLength is true, then
    1. Let targetLen be ? Get(Target, "length").
    2. If targetLen is a Number, then
      1. If targetLen is +∞𝔽, then
        1. Set L to +∞.
      2. Else if targetLen is -∞𝔽, then
        1. Set L to 0.
      3. Else,
        1. Let targetLenAsInt be ! ToIntegerOrInfinity(targetLen).
        2. Assert: targetLenAsInt is finite.
        3. Let argCount be the number of elements in args.
        4. Set L to max(targetLenAsInt - argCount, 0).
  7. Perform SetFunctionLength(F, L).
  8. Let targetName be ? Get(Target, "name").
  9. If targetName is not a String, set targetName to the empty String.
  10. Perform SetFunctionName(F, targetName, "bound").
  11. Return F.
Note 1

Function objects created using Function.prototype.bind are exotic objects. They also do not have a "prototype" property.

Note 2

If Target is either an arrow function or a bound function exotic object, then the thisArg passed to this method will not be used by subsequent calls to F.

20.2.3.3 Function.prototype.call ( thisArg, ...args )

This method performs the following steps when called:

  1. Let func be the this value.
  2. If IsCallable(func) is false, throw a TypeError exception.
  3. Perform PrepareForTailCall().
  4. Return ? Call(func, thisArg, args).
Note 1

The thisArg value is passed without modification as the this value. This is a change from Edition 3, where an undefined or null thisArg is replaced with the global object and ToObject is applied to all other values and that result is passed as the this value. Even though the thisArg is passed without modification, non-strict functions still perform these transformations upon entry to the function.

Note 2

If func is either an arrow function or a bound function exotic object, then the thisArg will be ignored by the function [[Call]] in step 4.

20.2.3.4 Function.prototype.constructor

The initial value of Function.prototype.constructor is %Function%.

20.2.3.5 Function.prototype.toString ( )

This method performs the following steps when called:

  1. Let func be the this value.
  2. If func is an Object, func has a [[SourceText]] internal slot, func.[[SourceText]] is a sequence of Unicode code points, and HostHasSourceTextAvailable(func) is true, then
    1. Return CodePointsToString(func.[[SourceText]]).
  3. If func is a built-in function object, return an implementation-defined String source code representation of func. The representation must have the syntax of a NativeFunction. Additionally, if func has an [[InitialName]] internal slot and func.[[InitialName]] is a String, the portion of the returned String that would be matched by NativeFunctionAccessoropt PropertyName must be func.[[InitialName]].
  4. If func is an Object and IsCallable(func) is true, return an implementation-defined String source code representation of func. The representation must have the syntax of a NativeFunction.
  5. Throw a TypeError exception.
NativeFunction : function NativeFunctionAccessoropt PropertyName[~Yield, ~Await]opt ( FormalParameters[~Yield, ~Await] ) { [ native code ] } NativeFunctionAccessor : get set

20.2.3.6 Function.prototype [ %Symbol.hasInstance% ] ( V )

This method performs the following steps when called:

  1. Let F be the this value.
  2. Return ? OrdinaryHasInstance(F, V).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

Note

This is the default implementation of %Symbol.hasInstance% that most functions inherit. %Symbol.hasInstance% is called by the instanceof operator to determine whether a value is an instance of a specific constructor. An expression such as

v instanceof F

evaluates as

F[%Symbol.hasInstance%](v)

A constructor function can control which objects are recognized as its instances by instanceof by exposing a different %Symbol.hasInstance% method on the function.

This property is non-writable and non-configurable to prevent tampering that could be used to globally expose the target function of a bound function.

The value of the "name" property of this method is "[Symbol.hasInstance]".

20.2.4 Function Instances

Every Function instance is an ECMAScript function object and has the internal slots listed in Table 30. Function objects created using the Function.prototype.bind method (20.2.3.2) have the internal slots listed in Table 31.

Function instances have the following properties:

20.2.4.1 length

The value of the "length" property is an integral Number that indicates the typical number of arguments expected by the function. However, the language permits the function to be invoked with some other number of arguments. The behaviour of a function when invoked on a number of arguments other than the number specified by its "length" property depends on the function. This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

20.2.4.2 name

The value of the "name" property is a String that is descriptive of the function. The name has no semantic significance but is typically a variable or property name that is used to refer to the function at its point of definition in ECMAScript source text. This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

Anonymous functions objects that do not have a contextual name associated with them by this specification use the empty String as the value of the "name" property.

20.2.4.3 prototype

Function instances that can be used as a constructor have a "prototype" property. Whenever such a Function instance is created another ordinary object is also created and is the initial value of the function's "prototype" property. Unless otherwise specified, the value of the "prototype" property is used to initialize the [[Prototype]] internal slot of the object created when that function is invoked as a constructor.

This property has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }.

Note

Function objects created using Function.prototype.bind, or by evaluating a MethodDefinition (that is not a GeneratorMethod or AsyncGeneratorMethod) or an ArrowFunction do not have a "prototype" property.

20.2.5 HostHasSourceTextAvailable ( func )

The host-defined abstract operation HostHasSourceTextAvailable takes argument func (a function object) and returns a Boolean. It allows host environments to prevent the source text from being provided for func.

An implementation of HostHasSourceTextAvailable must conform to the following requirements:

  • It must be deterministic with respect to its parameters. Each time it is called with a specific func as its argument, it must return the same result.

The default implementation of HostHasSourceTextAvailable is to return true.

20.3 Boolean Objects

20.3.1 The Boolean Constructor

The Boolean constructor:

  • is %Boolean%.
  • is the initial value of the "Boolean" property of the global object.
  • creates and initializes a new Boolean object when called as a constructor.
  • performs a type conversion when called as a function rather than as a constructor.
  • may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified Boolean behaviour must include a super call to the Boolean constructor to create and initialize the subclass instance with a [[BooleanData]] internal slot.

20.3.1.1 Boolean ( value )

This function performs the following steps when called:

  1. Let b be ToBoolean(value).
  2. If NewTarget is undefined, return b.
  3. Let O be ? OrdinaryCreateFromConstructor(NewTarget, "%Boolean.prototype%", « [[BooleanData]] »).
  4. Set O.[[BooleanData]] to b.
  5. Return O.

20.3.2 Properties of the Boolean Constructor

The Boolean constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

20.3.2.1 Boolean.prototype

The initial value of Boolean.prototype is the Boolean prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.3.3 Properties of the Boolean Prototype Object

The Boolean prototype object:

  • is %Boolean.prototype%.
  • is an ordinary object.
  • is itself a Boolean object; it has a [[BooleanData]] internal slot with the value false.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.

20.3.3.1 Boolean.prototype.constructor

The initial value of Boolean.prototype.constructor is %Boolean%.

20.3.3.2 Boolean.prototype.toString ( )

This method performs the following steps when called:

  1. Let b be ? ThisBooleanValue(this value).
  2. If b is true, return "true"; else return "false".

20.3.3.3 Boolean.prototype.valueOf ( )

This method performs the following steps when called:

  1. Return ? ThisBooleanValue(this value).

20.3.3.3.1 ThisBooleanValue ( value )

The abstract operation ThisBooleanValue takes argument value (an ECMAScript language value) and returns either a normal completion containing a Boolean or a throw completion. It performs the following steps when called:

  1. If value is a Boolean, return value.
  2. If value is an Object and value has a [[BooleanData]] internal slot, then
    1. Let b be value.[[BooleanData]].
    2. Assert: b is a Boolean.
    3. Return b.
  3. Throw a TypeError exception.

20.3.4 Properties of Boolean Instances

Boolean instances are ordinary objects that inherit properties from the Boolean prototype object. Boolean instances have a [[BooleanData]] internal slot. The [[BooleanData]] internal slot is the Boolean value represented by this Boolean object.

20.4 Symbol Objects

20.4.1 The Symbol Constructor

The Symbol constructor:

  • is %Symbol%.
  • is the initial value of the "Symbol" property of the global object.
  • returns a new Symbol value when called as a function.
  • is not intended to be used with the new operator.
  • is not intended to be subclassed.
  • may be used as the value of an extends clause of a class definition but a super call to it will cause an exception.

20.4.1.1 Symbol ( [ description ] )

This function performs the following steps when called:

  1. If NewTarget is not undefined, throw a TypeError exception.
  2. If description is undefined, let descString be undefined.
  3. Else, let descString be ? ToString(description).
  4. Return a new Symbol whose [[Description]] is descString.

20.4.2 Properties of the Symbol Constructor

The Symbol constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

20.4.2.1 Symbol.asyncIterator

The initial value of Symbol.asyncIterator is the well-known symbol %Symbol.asyncIterator% (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.4.2.2 Symbol.for ( key )

This function performs the following steps when called:

  1. Let stringKey be ? ToString(key).
  2. For each element e of the GlobalSymbolRegistry List, do
    1. If e.[[Key]] is stringKey, return e.[[Symbol]].
  3. Assert: The GlobalSymbolRegistry List does not currently contain an entry for stringKey.
  4. Let newSymbol be a new Symbol whose [[Description]] is stringKey.
  5. Append the GlobalSymbolRegistry Record { [[Key]]: stringKey, [[Symbol]]: newSymbol } to the GlobalSymbolRegistry List.
  6. Return newSymbol.

The GlobalSymbolRegistry List is an append-only List that is globally available. It is shared by all realms. Prior to the evaluation of any ECMAScript code, it is initialized as a new empty List. Elements of the GlobalSymbolRegistry List are Records with the structure defined in Table 63.

Table 63: GlobalSymbolRegistry Record Fields
Field Name Value Usage
[[Key]] a String A string key used to globally identify a Symbol.
[[Symbol]] a Symbol A symbol that can be retrieved from any realm.

20.4.2.3 Symbol.hasInstance

The initial value of Symbol.hasInstance is the well-known symbol %Symbol.hasInstance% (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.4.2.4 Symbol.isConcatSpreadable

The initial value of Symbol.isConcatSpreadable is the well-known symbol %Symbol.isConcatSpreadable% (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.4.2.5 Symbol.iterator

The initial value of Symbol.iterator is the well-known symbol %Symbol.iterator% (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.4.2.6 Symbol.keyFor ( sym )

This function performs the following steps when called:

  1. If sym is not a Symbol, throw a TypeError exception.
  2. Return KeyForSymbol(sym).

20.4.2.7 Symbol.match

The initial value of Symbol.match is the well-known symbol %Symbol.match% (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.4.2.8 Symbol.matchAll

The initial value of Symbol.matchAll is the well-known symbol %Symbol.matchAll% (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.4.2.9 Symbol.prototype

The initial value of Symbol.prototype is the Symbol prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.4.2.10 Symbol.replace

The initial value of Symbol.replace is the well-known symbol %Symbol.replace% (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.4.2.11 Symbol.search

The initial value of Symbol.search is the well-known symbol %Symbol.search% (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.4.2.12 Symbol.species

The initial value of Symbol.species is the well-known symbol %Symbol.species% (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.4.2.13 Symbol.split

The initial value of Symbol.split is the well-known symbol %Symbol.split% (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.4.2.14 Symbol.toPrimitive

The initial value of Symbol.toPrimitive is the well-known symbol %Symbol.toPrimitive% (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.4.2.15 Symbol.toStringTag

The initial value of Symbol.toStringTag is the well-known symbol %Symbol.toStringTag% (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.4.2.16 Symbol.unscopables

The initial value of Symbol.unscopables is the well-known symbol %Symbol.unscopables% (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.4.3 Properties of the Symbol Prototype Object

The Symbol prototype object:

20.4.3.1 Symbol.prototype.constructor

The initial value of Symbol.prototype.constructor is %Symbol%.

20.4.3.2 get Symbol.prototype.description

Symbol.prototype.description is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let s be the this value.
  2. Let sym be ? ThisSymbolValue(s).
  3. Return sym.[[Description]].

20.4.3.3 Symbol.prototype.toString ( )

This method performs the following steps when called:

  1. Let sym be ? ThisSymbolValue(this value).
  2. Return SymbolDescriptiveString(sym).

20.4.3.3.1 SymbolDescriptiveString ( sym )

The abstract operation SymbolDescriptiveString takes argument sym (a Symbol) and returns a String. It performs the following steps when called:

  1. Let desc be sym's [[Description]] value.
  2. If desc is undefined, set desc to the empty String.
  3. Assert: desc is a String.
  4. Return the string-concatenation of "Symbol(", desc, and ")".

20.4.3.4 Symbol.prototype.valueOf ( )

This method performs the following steps when called:

  1. Return ? ThisSymbolValue(this value).

20.4.3.4.1 ThisSymbolValue ( value )

The abstract operation ThisSymbolValue takes argument value (an ECMAScript language value) and returns either a normal completion containing a Symbol or a throw completion. It performs the following steps when called:

  1. If value is a Symbol, return value.
  2. If value is an Object and value has a [[SymbolData]] internal slot, then
    1. Let s be value.[[SymbolData]].
    2. Assert: s is a Symbol.
    3. Return s.
  3. Throw a TypeError exception.

20.4.3.5 Symbol.prototype [ %Symbol.toPrimitive% ] ( hint )

This method is called by ECMAScript language operators to convert a Symbol object to a primitive value.

It performs the following steps when called:

  1. Return ? ThisSymbolValue(this value).
Note

The argument is ignored.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

The value of the "name" property of this method is "[Symbol.toPrimitive]".

20.4.3.6 Symbol.prototype [ %Symbol.toStringTag% ]

The initial value of the %Symbol.toStringTag% property is the String value "Symbol".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

20.4.4 Properties of Symbol Instances

Symbol instances are ordinary objects that inherit properties from the Symbol prototype object. Symbol instances have a [[SymbolData]] internal slot. The [[SymbolData]] internal slot is the Symbol value represented by this Symbol object.

20.4.5 Abstract Operations for Symbols

20.4.5.1 KeyForSymbol ( sym )

The abstract operation KeyForSymbol takes argument sym (a Symbol) and returns a String or undefined. If sym is in the GlobalSymbolRegistry List, the String used to register sym will be returned. It performs the following steps when called:

  1. For each element e of the GlobalSymbolRegistry List, do
    1. If SameValue(e.[[Symbol]], sym) is true, return e.[[Key]].
  2. Assert: The GlobalSymbolRegistry List does not currently contain an entry for sym.
  3. Return undefined.

20.5 Error Objects

Instances of Error objects are thrown as exceptions when runtime errors occur. The Error objects may also serve as base objects for user-defined exception classes.

When an ECMAScript implementation detects a runtime error, it throws a new instance of one of the NativeError objects defined in 20.5.5 or a new instance of the AggregateError object defined in 20.5.7.

20.5.1 The Error Constructor

The Error constructor:

  • is %Error%.
  • is the initial value of the "Error" property of the global object.
  • creates and initializes a new Error object when called as a function rather than as a constructor. Thus the function call Error(…) is equivalent to the object creation expression new Error(…) with the same arguments.
  • may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified Error behaviour must include a super call to the Error constructor to create and initialize subclass instances with an [[ErrorData]] internal slot.

20.5.1.1 Error ( message [ , options ] )

This function performs the following steps when called:

  1. If NewTarget is undefined, let newTarget be the active function object; else let newTarget be NewTarget.
  2. Let O be ? OrdinaryCreateFromConstructor(newTarget, "%Error.prototype%", « [[ErrorData]] »).
  3. If message is not undefined, then
    1. Let msg be ? ToString(message).
    2. Perform CreateNonEnumerableDataPropertyOrThrow(O, "message", msg).
  4. Perform ? InstallErrorCause(O, options).
  5. Return O.

20.5.2 Properties of the Error Constructor

The Error constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

20.5.2.1 Error.isError ( arg )

This function performs the following steps when called:

  1. If arg is not an Object, return false.
  2. If arg does not have an [[ErrorData]] internal slot, return false.
  3. Return true.

20.5.2.2 Error.prototype

The initial value of Error.prototype is the Error prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.5.3 Properties of the Error Prototype Object

The Error prototype object:

  • is %Error.prototype%.
  • is an ordinary object.
  • is not an Error instance and does not have an [[ErrorData]] internal slot.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.

20.5.3.1 Error.prototype.constructor

The initial value of Error.prototype.constructor is %Error%.

20.5.3.2 Error.prototype.message

The initial value of Error.prototype.message is the empty String.

20.5.3.3 Error.prototype.name

The initial value of Error.prototype.name is "Error".

20.5.3.4 Error.prototype.toString ( )

This method performs the following steps when called:

  1. Let O be the this value.
  2. If O is not an Object, throw a TypeError exception.
  3. Let name be ? Get(O, "name").
  4. If name is undefined, set name to "Error"; otherwise set name to ? ToString(name).
  5. Let msg be ? Get(O, "message").
  6. If msg is undefined, set msg to the empty String; otherwise set msg to ? ToString(msg).
  7. If name is the empty String, return msg.
  8. If msg is the empty String, return name.
  9. Return the string-concatenation of name, the code unit 0x003A (COLON), the code unit 0x0020 (SPACE), and msg.

20.5.4 Properties of Error Instances

Error instances are ordinary objects that inherit properties from the Error prototype object and have an [[ErrorData]] internal slot whose value is undefined. The only specified use of [[ErrorData]] is to identify Error, AggregateError, and NativeError instances as Error objects within Object.prototype.toString and Error.isError.

20.5.5 Native Error Types Used in This Standard

A new instance of one of the NativeError objects below or of the AggregateError object is thrown when a runtime error is detected. All NativeError objects share the same structure, as described in 20.5.6.

20.5.5.1 EvalError

The EvalError constructor is %EvalError%.

This exception is not currently used within this specification. This object remains for compatibility with previous editions of this specification.

20.5.5.2 RangeError

The RangeError constructor is %RangeError%.

Indicates a value that is not in the set or range of allowable values.

20.5.5.3 ReferenceError

The ReferenceError constructor is %ReferenceError%.

Indicate that an invalid reference has been detected.

20.5.5.4 SyntaxError

The SyntaxError constructor is %SyntaxError%.

Indicates that a parsing error has occurred.

20.5.5.5 TypeError

The TypeError constructor is %TypeError%.

TypeError is used to indicate an unsuccessful operation when none of the other NativeError objects are an appropriate indication of the failure cause.

20.5.5.6 URIError

The URIError constructor is %URIError%.

Indicates that one of the global URI handling functions was used in a way that is incompatible with its definition.

20.5.6 NativeError Object Structure

Each of these objects has the structure described below, differing only in the name used as the constructor name and in the "name" property of the prototype object.

For each error object, references to NativeError in the definition should be replaced with the appropriate error object name from 20.5.5.

20.5.6.1 The NativeError Constructors

Each NativeError constructor:

  • creates and initializes a new NativeError object when called as a function rather than as a constructor. A call of the object as a function is equivalent to calling it as a constructor with the same arguments. Thus the function call NativeError(…) is equivalent to the object creation expression new NativeError(…) with the same arguments.
  • may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified NativeError behaviour must include a super call to the NativeError constructor to create and initialize subclass instances with an [[ErrorData]] internal slot.

20.5.6.1.1 NativeError ( message [ , options ] )

Each NativeError function performs the following steps when called:

  1. If NewTarget is undefined, let newTarget be the active function object; else let newTarget be NewTarget.
  2. Let O be ? OrdinaryCreateFromConstructor(newTarget, "%NativeError.prototype%", « [[ErrorData]] »).
  3. If message is not undefined, then
    1. Let msg be ? ToString(message).
    2. Perform CreateNonEnumerableDataPropertyOrThrow(O, "message", msg).
  4. Perform ? InstallErrorCause(O, options).
  5. Return O.

The actual value of the string passed in step 2 is either "%EvalError.prototype%", "%RangeError.prototype%", "%ReferenceError.prototype%", "%SyntaxError.prototype%", "%TypeError.prototype%", or "%URIError.prototype%" corresponding to which NativeError constructor is being defined.

20.5.6.2 Properties of the NativeError Constructors

Each NativeError constructor:

  • has a [[Prototype]] internal slot whose value is %Error%.
  • has a "name" property whose value is the String value "NativeError".
  • has the following properties:

20.5.6.2.1 NativeError.prototype

The initial value of NativeError.prototype is a NativeError prototype object (20.5.6.3). Each NativeError constructor has a distinct prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.5.6.3 Properties of the NativeError Prototype Objects

Each NativeError prototype object:

  • is an ordinary object.
  • is not an Error instance and does not have an [[ErrorData]] internal slot.
  • has a [[Prototype]] internal slot whose value is %Error.prototype%.

20.5.6.3.1 NativeError.prototype.constructor

The initial value of the "constructor" property of the prototype for a given NativeError constructor is the constructor itself.

20.5.6.3.2 NativeError.prototype.message

The initial value of the "message" property of the prototype for a given NativeError constructor is the empty String.

20.5.6.3.3 NativeError.prototype.name

The initial value of the "name" property of the prototype for a given NativeError constructor is the String value consisting of the name of the constructor (the name used instead of NativeError).

20.5.6.4 Properties of NativeError Instances

NativeError instances are ordinary objects that inherit properties from their NativeError prototype object and have an [[ErrorData]] internal slot whose value is undefined. The only specified use of [[ErrorData]] is by Object.prototype.toString (20.1.3.6) and Error.isError (20.5.2.1) to identify Error, AggregateError, or NativeError instances.

20.5.7 AggregateError Objects

20.5.7.1 The AggregateError Constructor

The AggregateError constructor:

  • is %AggregateError%.
  • is the initial value of the "AggregateError" property of the global object.
  • creates and initializes a new AggregateError object when called as a function rather than as a constructor. Thus the function call AggregateError(…) is equivalent to the object creation expression new AggregateError(…) with the same arguments.
  • may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified AggregateError behaviour must include a super call to the AggregateError constructor to create and initialize subclass instances with an [[ErrorData]] internal slot.

20.5.7.1.1 AggregateError ( errors, message [ , options ] )

This function performs the following steps when called:

  1. If NewTarget is undefined, let newTarget be the active function object; else let newTarget be NewTarget.
  2. Let O be ? OrdinaryCreateFromConstructor(newTarget, "%AggregateError.prototype%", « [[ErrorData]] »).
  3. If message is not undefined, then
    1. Let msg be ? ToString(message).
    2. Perform CreateNonEnumerableDataPropertyOrThrow(O, "message", msg).
  4. Perform ? InstallErrorCause(O, options).
  5. Let errorsList be ? IteratorToList(? GetIterator(errors, sync)).
  6. Perform ! DefinePropertyOrThrow(O, "errors", PropertyDescriptor { [[Configurable]]: true, [[Enumerable]]: false, [[Writable]]: true, [[Value]]: CreateArrayFromList(errorsList) }).
  7. Return O.

20.5.7.2 Properties of the AggregateError Constructor

The AggregateError constructor:

  • has a [[Prototype]] internal slot whose value is %Error%.
  • has the following properties:

20.5.7.2.1 AggregateError.prototype

The initial value of AggregateError.prototype is %AggregateError.prototype%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

20.5.7.3 Properties of the AggregateError Prototype Object

The AggregateError prototype object:

  • is %AggregateError.prototype%.
  • is an ordinary object.
  • is not an Error instance or an AggregateError instance and does not have an [[ErrorData]] internal slot.
  • has a [[Prototype]] internal slot whose value is %Error.prototype%.

20.5.7.3.1 AggregateError.prototype.constructor

The initial value of AggregateError.prototype.constructor is %AggregateError%.

20.5.7.3.2 AggregateError.prototype.message

The initial value of AggregateError.prototype.message is the empty String.

20.5.7.3.3 AggregateError.prototype.name

The initial value of AggregateError.prototype.name is "AggregateError".

20.5.7.4 Properties of AggregateError Instances

AggregateError instances are ordinary objects that inherit properties from their AggregateError prototype object and have an [[ErrorData]] internal slot whose value is undefined. The only specified use of [[ErrorData]] is by Object.prototype.toString (20.1.3.6) and Error.isError (20.5.2.1) to identify Error, AggregateError, or NativeError instances.

20.5.8 Abstract Operations for Error Objects

20.5.8.1 InstallErrorCause ( O, options )

The abstract operation InstallErrorCause takes arguments O (an Object) and options (an ECMAScript language value) and returns either a normal completion containing unused or a throw completion. It is used to create a "cause" property on O when a "cause" property is present on options. It performs the following steps when called:

  1. If options is an Object and ? HasProperty(options, "cause") is true, then
    1. Let cause be ? Get(options, "cause").
    2. Perform CreateNonEnumerableDataPropertyOrThrow(O, "cause", cause).
  2. Return unused.

21 Numbers and Dates

21.1 Number Objects

21.1.1 The Number Constructor

The Number constructor:

  • is %Number%.
  • is the initial value of the "Number" property of the global object.
  • creates and initializes a new Number object when called as a constructor.
  • performs a type conversion when called as a function rather than as a constructor.
  • may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified Number behaviour must include a super call to the Number constructor to create and initialize the subclass instance with a [[NumberData]] internal slot.

21.1.1.1 Number ( value )

This function performs the following steps when called:

  1. If value is present, then
    1. Let prim be ? ToNumeric(value).
    2. If prim is a BigInt, let n be 𝔽((prim)).
    3. Otherwise, let n be prim.
  2. Else,
    1. Let n be +0𝔽.
  3. If NewTarget is undefined, return n.
  4. Let O be ? OrdinaryCreateFromConstructor(NewTarget, "%Number.prototype%", « [[NumberData]] »).
  5. Set O.[[NumberData]] to n.
  6. Return O.

21.1.2 Properties of the Number Constructor

The Number constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

21.1.2.1 Number.EPSILON

The value of Number.EPSILON is the Number value for the magnitude of the difference between 1 and the smallest value greater than 1 that is representable as a Number value, which is approximately 2.2204460492503130808472633361816 × 10-16.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

21.1.2.2 Number.isFinite ( number )

This function performs the following steps when called:

  1. If number is not a Number, return false.
  2. If number is not finite, return false.
  3. Otherwise, return true.

21.1.2.3 Number.isInteger ( number )

This function performs the following steps when called:

  1. If number is an integral Number, return true.
  2. Return false.

21.1.2.4 Number.isNaN ( number )

This function performs the following steps when called:

  1. If number is not a Number, return false.
  2. If number is NaN, return true.
  3. Otherwise, return false.
Note

This function differs from the global isNaN function (19.2.3) in that it does not convert its argument to a Number before determining whether it is NaN.

21.1.2.5 Number.isSafeInteger ( number )

Note

An integer n is a "safe integer" if and only if the Number value for n is not the Number value for any other integer.

This function performs the following steps when called:

  1. If number is an integral Number, then
    1. If abs((number)) ≤ 253 - 1, return true.
  2. Return false.

21.1.2.6 Number.MAX_SAFE_INTEGER

Note

Due to rounding behaviour necessitated by precision limitations of IEEE 754-2019, the Number value for every integer greater than Number.MAX_SAFE_INTEGER is shared with at least one other integer. Such large-magnitude integers are therefore not safe, and are not guaranteed to be exactly representable as Number values or even to be distinguishable from each other. For example, both 9007199254740992 and 9007199254740993 evaluate to the Number value 9007199254740992𝔽.

The value of Number.MAX_SAFE_INTEGER is 9007199254740991𝔽 (𝔽(253 - 1)).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

21.1.2.7 Number.MAX_VALUE

The value of Number.MAX_VALUE is the largest positive finite value of the Number type, which is approximately 1.7976931348623157 × 10308.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

21.1.2.8 Number.MIN_SAFE_INTEGER

Note

Due to rounding behaviour necessitated by precision limitations of IEEE 754-2019, the Number value for every integer less than Number.MIN_SAFE_INTEGER is shared with at least one other integer. Such large-magnitude integers are therefore not safe, and are not guaranteed to be exactly representable as Number values or even to be distinguishable from each other. For example, both -9007199254740992 and -9007199254740993 evaluate to the Number value -9007199254740992𝔽.

The value of Number.MIN_SAFE_INTEGER is -9007199254740991𝔽 (𝔽(-(253 - 1))).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

21.1.2.9 Number.MIN_VALUE

The value of Number.MIN_VALUE is the smallest positive value of the Number type, which is approximately 5 × 10-324.

In the IEEE 754-2019 double precision binary representation, the smallest possible value is a denormalized number. If an implementation does not support denormalized values, the value of Number.MIN_VALUE must be the smallest non-zero positive value that can actually be represented by the implementation.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

21.1.2.10 Number.NaN

The value of Number.NaN is NaN.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

21.1.2.11 Number.NEGATIVE_INFINITY

The value of Number.NEGATIVE_INFINITY is -∞𝔽.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

21.1.2.12 Number.parseFloat ( string )

The initial value of the "parseFloat" property is %parseFloat%.

21.1.2.13 Number.parseInt ( string, radix )

The initial value of the "parseInt" property is %parseInt%.

21.1.2.14 Number.POSITIVE_INFINITY

The value of Number.POSITIVE_INFINITY is +∞𝔽.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

21.1.2.15 Number.prototype

The initial value of Number.prototype is the Number prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

21.1.3 Properties of the Number Prototype Object

The Number prototype object:

  • is %Number.prototype%.
  • is an ordinary object.
  • is itself a Number object; it has a [[NumberData]] internal slot with the value +0𝔽.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.

Unless explicitly stated otherwise, the methods of the Number prototype object defined below are not generic and the this value passed to them must be either a Number value or an object that has a [[NumberData]] internal slot that has been initialized to a Number value.

The phrase “this Number value” within the specification of a method refers to the result returned by calling the abstract operation ThisNumberValue with the this value of the method invocation passed as the argument.

21.1.3.1 Number.prototype.constructor

The initial value of Number.prototype.constructor is %Number%.

21.1.3.2 Number.prototype.toExponential ( fractionDigits )

This method returns a String containing this Number value represented in decimal exponential notation with one digit before the significand's decimal point and fractionDigits digits after the significand's decimal point. If fractionDigits is undefined, it includes as many significand digits as necessary to uniquely specify the Number (just like in ToString except that in this case the Number is always output in exponential notation).

It performs the following steps when called:

  1. Let x be ? ThisNumberValue(this value).
  2. Let f be ? ToIntegerOrInfinity(fractionDigits).
  3. Assert: If fractionDigits is undefined, then f is 0.
  4. If x is not finite, return Number::toString(x, 10).
  5. If f < 0 or f > 100, throw a RangeError exception.
  6. Set x to (x).
  7. Let s be the empty String.
  8. If x < 0, then
    1. Set s to "-".
    2. Set x to -x.
  9. If x = 0, then
    1. Let m be the String value consisting of f + 1 occurrences of the code unit 0x0030 (DIGIT ZERO).
    2. Let e be 0.
  10. Else,
    1. If fractionDigits is not undefined, then
      1. Let e and n be integers such that 10fn < 10f + 1 and for which n × 10e - f - x is as close to zero as possible. If there are two such sets of e and n, pick the e and n for which n × 10e - f is larger.
    2. Else,
      1. Let e, n, and ff be integers such that ff ≥ 0, 10ffn < 10ff + 1, 𝔽(n × 10e - ff) is 𝔽(x), and ff is as small as possible. Note that the decimal representation of n has ff + 1 digits, n is not divisible by 10, and the least significant digit of n is not necessarily uniquely determined by these criteria.
      2. Set f to ff.
    3. Let m be the String value consisting of the digits of the decimal representation of n (in order, with no leading zeroes).
  11. If f ≠ 0, then
    1. Let a be the first code unit of m.
    2. Let b be the other f code units of m.
    3. Set m to the string-concatenation of a, ".", and b.
  12. If e = 0, then
    1. Let c be "+".
    2. Let d be "0".
  13. Else,
    1. If e > 0, then
      1. Let c be "+".
    2. Else,
      1. Assert: e < 0.
      2. Let c be "-".
      3. Set e to -e.
    3. Let d be the String value consisting of the digits of the decimal representation of e (in order, with no leading zeroes).
  14. Set m to the string-concatenation of m, "e", c, and d.
  15. Return the string-concatenation of s and m.
Note

For implementations that provide more accurate conversions than required by the rules above, it is recommended that the following alternative version of step 10.b.i be used as a guideline:

  1. Let e, n, and f be integers such that f ≥ 0, 10fn < 10f + 1, 𝔽(n × 10e - f) is 𝔽(x), and f is as small as possible. If there are multiple possibilities for n, choose the value of n for which 𝔽(n × 10e - f) is closest in value to 𝔽(x). If there are two such possible values of n, choose the one that is even.

21.1.3.3 Number.prototype.toFixed ( fractionDigits )

Note 1

This method returns a String containing this Number value represented in decimal fixed-point notation with fractionDigits digits after the decimal point. If fractionDigits is undefined, 0 is assumed.

It performs the following steps when called:

  1. Let x be ? ThisNumberValue(this value).
  2. Let f be ? ToIntegerOrInfinity(fractionDigits).
  3. Assert: If fractionDigits is undefined, then f is 0.
  4. If f is not finite, throw a RangeError exception.
  5. If f < 0 or f > 100, throw a RangeError exception.
  6. If x is not finite, return Number::toString(x, 10).
  7. Set x to (x).
  8. Let s be the empty String.
  9. If x < 0, then
    1. Set s to "-".
    2. Set x to -x.
  10. If x ≥ 1021, then
    1. Let m be ! ToString(𝔽(x)).
  11. Else,
    1. Let n be an integer for which n / 10f - x is as close to zero as possible. If there are two such n, pick the larger n.
    2. If n = 0, let m be "0"; otherwise let m be the String value consisting of the digits of the decimal representation of n (in order, with no leading zeroes).
    3. If f ≠ 0, then
      1. Let k be the length of m.
      2. If kf, then
        1. Let z be the String value consisting of f + 1 - k occurrences of the code unit 0x0030 (DIGIT ZERO).
        2. Set m to the string-concatenation of z and m.
        3. Set k to f + 1.
      3. Let a be the first k - f code units of m.
      4. Let b be the other f code units of m.
      5. Set m to the string-concatenation of a, ".", and b.
  12. Return the string-concatenation of s and m.
Note 2

The output of toFixed may be more precise than toString for some values because toString only prints enough significant digits to distinguish the number from adjacent Number values. For example,

(1000000000000000128).toString() returns "1000000000000000100", while
(1000000000000000128).toFixed(0) returns "1000000000000000128".

21.1.3.4 Number.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] )

An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement this method as specified in the ECMA-402 specification. If an ECMAScript implementation does not include the ECMA-402 API the following specification of this method is used:

This method produces a String value that represents this Number value formatted according to the conventions of the host environment's current locale. This method is implementation-defined, and it is permissible, but not encouraged, for it to return the same thing as toString.

The meanings of the optional parameters to this method are defined in the ECMA-402 specification; implementations that do not include ECMA-402 support must not use those parameter positions for anything else.

21.1.3.5 Number.prototype.toPrecision ( precision )

This method returns a String containing this Number value represented either in decimal exponential notation with one digit before the significand's decimal point and precision - 1 digits after the significand's decimal point or in decimal fixed notation with precision significant digits. If precision is undefined, it calls ToString instead.

It performs the following steps when called:

  1. Let x be ? ThisNumberValue(this value).
  2. If precision is undefined, return ! ToString(x).
  3. Let p be ? ToIntegerOrInfinity(precision).
  4. If x is not finite, return Number::toString(x, 10).
  5. If p < 1 or p > 100, throw a RangeError exception.
  6. Set x to (x).
  7. Let s be the empty String.
  8. If x < 0, then
    1. Set s to the code unit 0x002D (HYPHEN-MINUS).
    2. Set x to -x.
  9. If x = 0, then
    1. Let m be the String value consisting of p occurrences of the code unit 0x0030 (DIGIT ZERO).
    2. Let e be 0.
  10. Else,
    1. Let e and n be integers such that 10p - 1n < 10p and for which n × 10e - p + 1 - x is as close to zero as possible. If there are two such sets of e and n, pick the e and n for which n × 10e - p + 1 is larger.
    2. Let m be the String value consisting of the digits of the decimal representation of n (in order, with no leading zeroes).
    3. If e < -6 or ep, then
      1. Assert: e ≠ 0.
      2. If p ≠ 1, then
        1. Let a be the first code unit of m.
        2. Let b be the other p - 1 code units of m.
        3. Set m to the string-concatenation of a, ".", and b.
      3. If e > 0, then
        1. Let c be the code unit 0x002B (PLUS SIGN).
      4. Else,
        1. Assert: e < 0.
        2. Let c be the code unit 0x002D (HYPHEN-MINUS).
        3. Set e to -e.
      5. Let d be the String value consisting of the digits of the decimal representation of e (in order, with no leading zeroes).
      6. Return the string-concatenation of s, m, the code unit 0x0065 (LATIN SMALL LETTER E), c, and d.
  11. If e = p - 1, return the string-concatenation of s and m.
  12. If e ≥ 0, then
    1. Set m to the string-concatenation of the first e + 1 code units of m, the code unit 0x002E (FULL STOP), and the remaining p - (e + 1) code units of m.
  13. Else,
    1. Set m to the string-concatenation of the code unit 0x0030 (DIGIT ZERO), the code unit 0x002E (FULL STOP), -(e + 1) occurrences of the code unit 0x0030 (DIGIT ZERO), and the String m.
  14. Return the string-concatenation of s and m.

21.1.3.6 Number.prototype.toString ( [ radix ] )

Note

The optional radix should be an integral Number value in the inclusive interval from 2𝔽 to 36𝔽. If radix is undefined then 10𝔽 is used as the value of radix.

This method performs the following steps when called:

  1. Let x be ? ThisNumberValue(this value).
  2. If radix is undefined, let radixMV be 10.
  3. Else, let radixMV be ? ToIntegerOrInfinity(radix).
  4. If radixMV is not in the inclusive interval from 2 to 36, throw a RangeError exception.
  5. Return Number::toString(x, radixMV).

This method is not generic; it throws a TypeError exception if its this value is not a Number or a Number object. Therefore, it cannot be transferred to other kinds of objects for use as a method.

The "length" property of this method is 1𝔽.

21.1.3.7 Number.prototype.valueOf ( )

  1. Return ? ThisNumberValue(this value).

21.1.3.7.1 ThisNumberValue ( value )

The abstract operation ThisNumberValue takes argument value (an ECMAScript language value) and returns either a normal completion containing a Number or a throw completion. It performs the following steps when called:

  1. If value is a Number, return value.
  2. If value is an Object and value has a [[NumberData]] internal slot, then
    1. Let n be value.[[NumberData]].
    2. Assert: n is a Number.
    3. Return n.
  3. Throw a TypeError exception.

21.1.4 Properties of Number Instances

Number instances are ordinary objects that inherit properties from the Number prototype object. Number instances also have a [[NumberData]] internal slot. The [[NumberData]] internal slot is the Number value represented by this Number object.

21.2 BigInt Objects

21.2.1 The BigInt Constructor

The BigInt constructor:

  • is %BigInt%.
  • is the initial value of the "BigInt" property of the global object.
  • performs a type conversion when called as a function rather than as a constructor.
  • is not intended to be used with the new operator or to be subclassed. It may be used as the value of an extends clause of a class definition but a super call to the BigInt constructor will cause an exception.

21.2.1.1 BigInt ( value )

This function performs the following steps when called:

  1. If NewTarget is not undefined, throw a TypeError exception.
  2. Let prim be ? ToPrimitive(value, number).
  3. If prim is a Number, return ? NumberToBigInt(prim).
  4. Otherwise, return ? ToBigInt(prim).

21.2.1.1.1 NumberToBigInt ( number )

The abstract operation NumberToBigInt takes argument number (a Number) and returns either a normal completion containing a BigInt or a throw completion. It performs the following steps when called:

  1. If number is not an integral Number, throw a RangeError exception.
  2. Return ((number)).

21.2.2 Properties of the BigInt Constructor

The BigInt constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

21.2.2.1 BigInt.asIntN ( bits, bigint )

This function performs the following steps when called:

  1. Set bits to ? ToIndex(bits).
  2. Set bigint to ? ToBigInt(bigint).
  3. Let mod be (bigint) modulo 2bits.
  4. If mod ≥ 2bits - 1, return (mod - 2bits); otherwise return (mod).

21.2.2.2 BigInt.asUintN ( bits, bigint )

This function performs the following steps when called:

  1. Set bits to ? ToIndex(bits).
  2. Set bigint to ? ToBigInt(bigint).
  3. Return ((bigint) modulo 2bits).

21.2.2.3 BigInt.prototype

The initial value of BigInt.prototype is the BigInt prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

21.2.3 Properties of the BigInt Prototype Object

The BigInt prototype object:

The phrase “this BigInt value” within the specification of a method refers to the result returned by calling the abstract operation ThisBigIntValue with the this value of the method invocation passed as the argument.

21.2.3.1 BigInt.prototype.constructor

The initial value of BigInt.prototype.constructor is %BigInt%.

21.2.3.2 BigInt.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] )

An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement this method as specified in the ECMA-402 specification. If an ECMAScript implementation does not include the ECMA-402 API the following specification of this method is used:

This method produces a String value that represents this BigInt value formatted according to the conventions of the host environment's current locale. This method is implementation-defined, and it is permissible, but not encouraged, for it to return the same thing as toString.

The meanings of the optional parameters to this method are defined in the ECMA-402 specification; implementations that do not include ECMA-402 support must not use those parameter positions for anything else.

21.2.3.3 BigInt.prototype.toString ( [ radix ] )

Note

The optional radix should be an integral Number value in the inclusive interval from 2𝔽 to 36𝔽. If radix is undefined then 10𝔽 is used as the value of radix.

This method performs the following steps when called:

  1. Let x be ? ThisBigIntValue(this value).
  2. If radix is undefined, let radixMV be 10.
  3. Else, let radixMV be ? ToIntegerOrInfinity(radix).
  4. If radixMV is not in the inclusive interval from 2 to 36, throw a RangeError exception.
  5. Return BigInt::toString(x, radixMV).

This method is not generic; it throws a TypeError exception if its this value is not a BigInt or a BigInt object. Therefore, it cannot be transferred to other kinds of objects for use as a method.

21.2.3.4 BigInt.prototype.valueOf ( )

  1. Return ? ThisBigIntValue(this value).

21.2.3.4.1 ThisBigIntValue ( value )

The abstract operation ThisBigIntValue takes argument value (an ECMAScript language value) and returns either a normal completion containing a BigInt or a throw completion. It performs the following steps when called:

  1. If value is a BigInt, return value.
  2. If value is an Object and value has a [[BigIntData]] internal slot, then
    1. Assert: value.[[BigIntData]] is a BigInt.
    2. Return value.[[BigIntData]].
  3. Throw a TypeError exception.

21.2.3.5 BigInt.prototype [ %Symbol.toStringTag% ]

The initial value of the %Symbol.toStringTag% property is the String value "BigInt".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

21.2.4 Properties of BigInt Instances

BigInt instances are ordinary objects that inherit properties from the BigInt prototype object. BigInt instances also have a [[BigIntData]] internal slot. The [[BigIntData]] internal slot is the BigInt value represented by this BigInt object.

21.3 The Math Object

The Math object:

  • is %Math%.
  • is the initial value of the "Math" property of the global object.
  • is an ordinary object.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.
  • is not a function object.
  • does not have a [[Construct]] internal method; it cannot be used as a constructor with the new operator.
  • does not have a [[Call]] internal method; it cannot be invoked as a function.
Note

In this specification, the phrase “the Number value for x” has a technical meaning defined in 6.1.6.1.

21.3.1 Value Properties of the Math Object

21.3.1.1 Math.E

The Number value for e, the base of the natural logarithms, which is approximately 2.7182818284590452354.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

21.3.1.2 Math.LN10

The Number value for the natural logarithm of 10, which is approximately 2.302585092994046.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

21.3.1.3 Math.LN2

The Number value for the natural logarithm of 2, which is approximately 0.6931471805599453.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

21.3.1.4 Math.LOG10E

The Number value for the base-10 logarithm of e, the base of the natural logarithms; this value is approximately 0.4342944819032518.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

Note

The value of Math.LOG10E is approximately the reciprocal of the value of Math.LN10.

21.3.1.5 Math.LOG2E

The Number value for the base-2 logarithm of e, the base of the natural logarithms; this value is approximately 1.4426950408889634.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

Note

The value of Math.LOG2E is approximately the reciprocal of the value of Math.LN2.

21.3.1.6 Math.PI

The Number value for π, the ratio of the circumference of a circle to its diameter, which is approximately 3.1415926535897932.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

21.3.1.7 Math.SQRT1_2

The Number value for the square root of ½, which is approximately 0.7071067811865476.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

Note

The value of Math.SQRT1_2 is approximately the reciprocal of the value of Math.SQRT2.

21.3.1.8 Math.SQRT2

The Number value for the square root of 2, which is approximately 1.4142135623730951.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

21.3.1.9 Math [ %Symbol.toStringTag% ]

The initial value of the %Symbol.toStringTag% property is the String value "Math".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

21.3.2 Function Properties of the Math Object

Note

The behaviour of the functions acos, acosh, asin, asinh, atan, atanh, atan2, cbrt, cos, cosh, exp, expm1, hypot, log, log1p, log2, log10, pow, random, sin, sinh, tan, and tanh is not precisely specified here except to require specific results for certain argument values that represent boundary cases of interest. For other argument values, these functions are intended to compute approximations to the results of familiar mathematical functions, but some latitude is allowed in the choice of approximation algorithms. The general intent is that an implementer should be able to use the same mathematical library for ECMAScript on a given hardware platform that is available to C programmers on that platform.

Although the choice of algorithms is left to the implementation, it is recommended (but not specified by this standard) that implementations use the approximation algorithms for IEEE 754-2019 arithmetic contained in fdlibm, the freely distributable mathematical library from Sun Microsystems (http://www.netlib.org/fdlibm).

21.3.2.1 Math.abs ( x )

This function returns the absolute value of x; the result has the same magnitude as x but has positive sign.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is NaN, return NaN.
  3. If n is -0𝔽, return +0𝔽.
  4. If n is -∞𝔽, return +∞𝔽.
  5. If n < -0𝔽, return -n.
  6. Return n.

21.3.2.2 Math.acos ( x )

This function returns the inverse cosine of x. The result is expressed in radians and is in the inclusive interval from +0𝔽 to 𝔽(π).

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is NaN, n > 1𝔽, or n < -1𝔽, return NaN.
  3. If n is 1𝔽, return +0𝔽.
  4. Return an implementation-approximated Number value representing the inverse cosine of (n).

21.3.2.3 Math.acosh ( x )

This function returns the inverse hyperbolic cosine of x.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is either NaN or +∞𝔽, return n.
  3. If n is 1𝔽, return +0𝔽.
  4. If n < 1𝔽, return NaN.
  5. Return an implementation-approximated Number value representing the inverse hyperbolic cosine of (n).

21.3.2.4 Math.asin ( x )

This function returns the inverse sine of x. The result is expressed in radians and is in the inclusive interval from 𝔽(-π / 2) to 𝔽(π / 2).

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is one of NaN, +0𝔽, or -0𝔽, return n.
  3. If n > 1𝔽 or n < -1𝔽, return NaN.
  4. Return an implementation-approximated Number value representing the inverse sine of (n).

21.3.2.5 Math.asinh ( x )

This function returns the inverse hyperbolic sine of x.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is not finite or n is either +0𝔽 or -0𝔽, return n.
  3. Return an implementation-approximated Number value representing the inverse hyperbolic sine of (n).

21.3.2.6 Math.atan ( x )

This function returns the inverse tangent of x. The result is expressed in radians and is in the inclusive interval from 𝔽(-π / 2) to 𝔽(π / 2).

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is one of NaN, +0𝔽, or -0𝔽, return n.
  3. If n is +∞𝔽, return an implementation-approximated Number value representing π / 2.
  4. If n is -∞𝔽, return an implementation-approximated Number value representing -π / 2.
  5. Return an implementation-approximated Number value representing the inverse tangent of (n).

21.3.2.7 Math.atanh ( x )

This function returns the inverse hyperbolic tangent of x.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is one of NaN, +0𝔽, or -0𝔽, return n.
  3. If n > 1𝔽 or n < -1𝔽, return NaN.
  4. If n is 1𝔽, return +∞𝔽.
  5. If n is -1𝔽, return -∞𝔽.
  6. Return an implementation-approximated Number value representing the inverse hyperbolic tangent of (n).

21.3.2.8 Math.atan2 ( y, x )

This function returns the inverse tangent of the quotient y / x of the arguments y and x, where the signs of y and x are used to determine the quadrant of the result. Note that it is intentional and traditional for the two-argument inverse tangent function that the argument named y be first and the argument named x be second. The result is expressed in radians and is in the inclusive interval from -π to +π.

It performs the following steps when called:

  1. Let ny be ? ToNumber(y).
  2. Let nx be ? ToNumber(x).
  3. If ny is NaN or nx is NaN, return NaN.
  4. If ny is +∞𝔽, then
    1. If nx is +∞𝔽, return an implementation-approximated Number value representing π / 4.
    2. If nx is -∞𝔽, return an implementation-approximated Number value representing 3π / 4.
    3. Return an implementation-approximated Number value representing π / 2.
  5. If ny is -∞𝔽, then
    1. If nx is +∞𝔽, return an implementation-approximated Number value representing -π / 4.
    2. If nx is -∞𝔽, return an implementation-approximated Number value representing -3π / 4.
    3. Return an implementation-approximated Number value representing -π / 2.
  6. If ny is +0𝔽, then
    1. If nx > +0𝔽 or nx is +0𝔽, return +0𝔽.
    2. Return an implementation-approximated Number value representing π.
  7. If ny is -0𝔽, then
    1. If nx > +0𝔽 or nx is +0𝔽, return -0𝔽.
    2. Return an implementation-approximated Number value representing -π.
  8. Assert: ny is finite and is neither +0𝔽 nor -0𝔽.
  9. If ny > +0𝔽, then
    1. If nx is +∞𝔽, return +0𝔽.
    2. If nx is -∞𝔽, return an implementation-approximated Number value representing π.
    3. If nx is either +0𝔽 or -0𝔽, return an implementation-approximated Number value representing π / 2.
  10. If ny < -0𝔽, then
    1. If nx is +∞𝔽, return -0𝔽.
    2. If nx is -∞𝔽, return an implementation-approximated Number value representing -π.
    3. If nx is either +0𝔽 or -0𝔽, return an implementation-approximated Number value representing -π / 2.
  11. Assert: nx is finite and is neither +0𝔽 nor -0𝔽.
  12. Let r be the inverse tangent of abs((ny) / (nx)).
  13. If nx < -0𝔽, then
    1. If ny > +0𝔽, set r to π - r.
    2. Else, set r to -π + r.
  14. Else,
    1. If ny < -0𝔽, set r to -r.
  15. Return an implementation-approximated Number value representing r.

21.3.2.9 Math.cbrt ( x )

This function returns the cube root of x.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is not finite or n is either +0𝔽 or -0𝔽, return n.
  3. Return an implementation-approximated Number value representing the cube root of (n).

21.3.2.10 Math.ceil ( x )

This function returns the smallest (closest to -∞) integral Number value that is not less than x. If x is already an integral Number, the result is x.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is not finite or n is either +0𝔽 or -0𝔽, return n.
  3. If n < -0𝔽 and n > -1𝔽, return -0𝔽.
  4. If n is an integral Number, return n.
  5. Return the smallest (closest to -∞) integral Number value that is not less than n.
Note

The value of Math.ceil(x) is the same as the value of -Math.floor(-x).

21.3.2.11 Math.clz32 ( x )

This function performs the following steps when called:

  1. Let n be ? ToUint32(x).
  2. Let p be the number of leading zero bits in the unsigned 32-bit binary representation of n.
  3. Return 𝔽(p).
Note

If n is either +0𝔽 or -0𝔽, this method returns 32𝔽. If the most significant bit of the 32-bit binary encoding of n is 1, this method returns +0𝔽.

21.3.2.12 Math.cos ( x )

This function returns the cosine of x. The argument is expressed in radians.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is not finite, return NaN.
  3. If n is either +0𝔽 or -0𝔽, return 1𝔽.
  4. Return an implementation-approximated Number value representing the cosine of (n).

21.3.2.13 Math.cosh ( x )

This function returns the hyperbolic cosine of x.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is NaN, return NaN.
  3. If n is either +∞𝔽 or -∞𝔽, return +∞𝔽.
  4. If n is either +0𝔽 or -0𝔽, return 1𝔽.
  5. Return an implementation-approximated Number value representing the hyperbolic cosine of (n).
Note

The value of Math.cosh(x) is the same as the value of (Math.exp(x) + Math.exp(-x)) / 2.

21.3.2.14 Math.exp ( x )

This function returns the exponential function of x (e raised to the power of x, where e is the base of the natural logarithms).

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is either NaN or +∞𝔽, return n.
  3. If n is either +0𝔽 or -0𝔽, return 1𝔽.
  4. If n is -∞𝔽, return +0𝔽.
  5. Return an implementation-approximated Number value representing the exponential function of (n).

21.3.2.15 Math.expm1 ( x )

This function returns the result of subtracting 1 from the exponential function of x (e raised to the power of x, where e is the base of the natural logarithms). The result is computed in a way that is accurate even when the value of x is close to 0.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is one of NaN, +0𝔽, -0𝔽, or +∞𝔽, return n.
  3. If n is -∞𝔽, return -1𝔽.
  4. Let exp be the exponential function of (n).
  5. Return an implementation-approximated Number value representing exp - 1.

21.3.2.16 Math.floor ( x )

This function returns the greatest (closest to +∞) integral Number value that is not greater than x. If x is already an integral Number, the result is x.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is not finite or n is either +0𝔽 or -0𝔽, return n.
  3. If n < 1𝔽 and n > +0𝔽, return +0𝔽.
  4. If n is an integral Number, return n.
  5. Return the greatest (closest to +∞) integral Number value that is not greater than n.
Note

The value of Math.floor(x) is the same as the value of -Math.ceil(-x).

21.3.2.17 Math.fround ( x )

This function performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is NaN, return NaN.
  3. If n is one of +0𝔽, -0𝔽, +∞𝔽, or -∞𝔽, return n.
  4. Let n32 be the result of converting n to IEEE 754-2019 binary32 format using roundTiesToEven mode.
  5. Let n64 be the result of converting n32 to IEEE 754-2019 binary64 format.
  6. Return the ECMAScript Number value corresponding to n64.

21.3.2.18 Math.f16round ( x )

This function performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is NaN, return NaN.
  3. If n is one of +0𝔽, -0𝔽, +∞𝔽, or -∞𝔽, return n.
  4. Let n16 be the result of converting n to IEEE 754-2019 binary16 format using roundTiesToEven mode.
  5. Let n64 be the result of converting n16 to IEEE 754-2019 binary64 format.
  6. Return the ECMAScript Number value corresponding to n64.
Note

This operation is not the same as casting to binary32 and then to binary16 because of the possibility of double-rounding: consider the number k = 1.00048828125000022204𝔽, for example, for which Math.f16round(k) is 1.0009765625𝔽, but Math.f16round(Math.fround(k)) is 1𝔽.

Not all platforms provide native support for casting from binary64 to binary16. There are various libraries which can provide this, including the MIT-licensed half library. Alternatively, it is possible to first cast from binary64 to binary32 under roundTiesToEven and then check whether the result could lead to incorrect double-rounding. The cases which could can be handled explicitly by adjusting the mantissa of the binary32 value so that it is the value which would be produced by performing the initial cast under roundTiesToOdd. Casting the adjusted value to binary16 under roundTiesToEven then produces the correct value.

21.3.2.19 Math.hypot ( ...args )

Given zero or more arguments, this function returns the square root of the sum of squares of its arguments.

It performs the following steps when called:

  1. Let coerced be a new empty List.
  2. For each element arg of args, do
    1. Let n be ? ToNumber(arg).
    2. Append n to coerced.
  3. For each element number of coerced, do
    1. If number is either +∞𝔽 or -∞𝔽, return +∞𝔽.
  4. Let onlyZero be true.
  5. For each element number of coerced, do
    1. If number is NaN, return NaN.
    2. If number is neither +0𝔽 nor -0𝔽, set onlyZero to false.
  6. If onlyZero is true, return +0𝔽.
  7. Return an implementation-approximated Number value representing the square root of the sum of squares of the mathematical values of the elements of coerced.

The "length" property of this function is 2𝔽.

Note

Implementations should take care to avoid the loss of precision from overflows and underflows that are prone to occur in naive implementations when this function is called with two or more arguments.

21.3.2.20 Math.imul ( x, y )

This function performs the following steps when called:

  1. Let a be (? ToUint32(x)).
  2. Let b be (? ToUint32(y)).
  3. Let product be (a × b) modulo 232.
  4. If product ≥ 231, return 𝔽(product - 232); otherwise return 𝔽(product).

21.3.2.21 Math.log ( x )

This function returns the natural logarithm of x.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is either NaN or +∞𝔽, return n.
  3. If n is 1𝔽, return +0𝔽.
  4. If n is either +0𝔽 or -0𝔽, return -∞𝔽.
  5. If n < -0𝔽, return NaN.
  6. Return an implementation-approximated Number value representing the natural logarithm of (n).

21.3.2.22 Math.log1p ( x )

This function returns the natural logarithm of 1 + x. The result is computed in a way that is accurate even when the value of x is close to zero.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is one of NaN, +0𝔽, -0𝔽, or +∞𝔽, return n.
  3. If n is -1𝔽, return -∞𝔽.
  4. If n < -1𝔽, return NaN.
  5. Return an implementation-approximated Number value representing the natural logarithm of 1 + (n).

21.3.2.23 Math.log10 ( x )

This function returns the base 10 logarithm of x.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is either NaN or +∞𝔽, return n.
  3. If n is 1𝔽, return +0𝔽.
  4. If n is either +0𝔽 or -0𝔽, return -∞𝔽.
  5. If n < -0𝔽, return NaN.
  6. Return an implementation-approximated Number value representing the base 10 logarithm of (n).

21.3.2.24 Math.log2 ( x )

This function returns the base 2 logarithm of x.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is either NaN or +∞𝔽, return n.
  3. If n is 1𝔽, return +0𝔽.
  4. If n is either +0𝔽 or -0𝔽, return -∞𝔽.
  5. If n < -0𝔽, return NaN.
  6. Return an implementation-approximated Number value representing the base 2 logarithm of (n).

21.3.2.25 Math.max ( ...args )

Given zero or more arguments, this function calls ToNumber on each of the arguments and returns the largest of the resulting values.

It performs the following steps when called:

  1. Let coerced be a new empty List.
  2. For each element arg of args, do
    1. Let n be ? ToNumber(arg).
    2. Append n to coerced.
  3. Let highest be -∞𝔽.
  4. For each element number of coerced, do
    1. If number is NaN, return NaN.
    2. If number is +0𝔽 and highest is -0𝔽, set highest to +0𝔽.
    3. If number > highest, set highest to number.
  5. Return highest.
Note

The comparison of values to determine the largest value is done using the IsLessThan algorithm except that +0𝔽 is considered to be larger than -0𝔽.

The "length" property of this function is 2𝔽.

21.3.2.26 Math.min ( ...args )

Given zero or more arguments, this function calls ToNumber on each of the arguments and returns the smallest of the resulting values.

It performs the following steps when called:

  1. Let coerced be a new empty List.
  2. For each element arg of args, do
    1. Let n be ? ToNumber(arg).
    2. Append n to coerced.
  3. Let lowest be +∞𝔽.
  4. For each element number of coerced, do
    1. If number is NaN, return NaN.
    2. If number is -0𝔽 and lowest is +0𝔽, set lowest to -0𝔽.
    3. If number < lowest, set lowest to number.
  5. Return lowest.
Note

The comparison of values to determine the largest value is done using the IsLessThan algorithm except that +0𝔽 is considered to be larger than -0𝔽.

The "length" property of this function is 2𝔽.

21.3.2.27 Math.pow ( base, exponent )

This function performs the following steps when called:

  1. Set base to ? ToNumber(base).
  2. Set exponent to ? ToNumber(exponent).
  3. Return Number::exponentiate(base, exponent).

21.3.2.28 Math.random ( )

This function returns a Number value with positive sign, greater than or equal to +0𝔽 but strictly less than 1𝔽, chosen randomly or pseudo randomly with approximately uniform distribution over that range, using an implementation-defined algorithm or strategy.

Each Math.random function created for distinct realms must produce a distinct sequence of values from successive calls.

21.3.2.29 Math.round ( x )

This function returns the Number value that is closest to x and is integral. If two integral Numbers are equally close to x, then the result is the Number value that is closer to +∞. If x is already integral, the result is x.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is not finite or n is an integral Number, return n.
  3. If n < 0.5𝔽 and n > +0𝔽, return +0𝔽.
  4. If n < -0𝔽 and n-0.5𝔽, return -0𝔽.
  5. Return the integral Number closest to n, preferring the Number closer to +∞ in the case of a tie.
Note 1

Math.round(3.5) returns 4, but Math.round(-3.5) returns -3.

Note 2

The value of Math.round(x) is not always the same as the value of Math.floor(x + 0.5). When x is -0𝔽 or x is less than -0𝔽 but greater than or equal to -0.5𝔽, Math.round(x) returns -0𝔽, but Math.floor(x + 0.5) returns +0𝔽. Math.round(x) may also differ from the value of Math.floor(x + 0.5)because of internal rounding when computing x + 0.5.

21.3.2.30 Math.sign ( x )

This function returns the sign of x, indicating whether x is positive, negative, or zero.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is one of NaN, +0𝔽, or -0𝔽, return n.
  3. If n < -0𝔽, return -1𝔽.
  4. Return 1𝔽.

21.3.2.31 Math.sin ( x )

This function returns the sine of x. The argument is expressed in radians.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is one of NaN, +0𝔽, or -0𝔽, return n.
  3. If n is either +∞𝔽 or -∞𝔽, return NaN.
  4. Return an implementation-approximated Number value representing the sine of (n).

21.3.2.32 Math.sinh ( x )

This function returns the hyperbolic sine of x.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is not finite or n is either +0𝔽 or -0𝔽, return n.
  3. Return an implementation-approximated Number value representing the hyperbolic sine of (n).
Note

The value of Math.sinh(x) is the same as the value of (Math.exp(x) - Math.exp(-x)) / 2.

21.3.2.33 Math.sqrt ( x )

This function returns the square root of x.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is one of NaN, +0𝔽, -0𝔽, or +∞𝔽, return n.
  3. If n < -0𝔽, return NaN.
  4. Return 𝔽(the square root of (n)).

21.3.2.34 Math.tan ( x )

This function returns the tangent of x. The argument is expressed in radians.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is one of NaN, +0𝔽, or -0𝔽, return n.
  3. If n is either +∞𝔽 or -∞𝔽, return NaN.
  4. Return an implementation-approximated Number value representing the tangent of (n).

21.3.2.35 Math.tanh ( x )

This function returns the hyperbolic tangent of x.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is one of NaN, +0𝔽, or -0𝔽, return n.
  3. If n is +∞𝔽, return 1𝔽.
  4. If n is -∞𝔽, return -1𝔽.
  5. Return an implementation-approximated Number value representing the hyperbolic tangent of (n).
Note

The value of Math.tanh(x) is the same as the value of (Math.exp(x) - Math.exp(-x)) / (Math.exp(x) + Math.exp(-x)).

21.3.2.36 Math.trunc ( x )

This function returns the integral part of the number x, removing any fractional digits. If x is already integral, the result is x.

It performs the following steps when called:

  1. Let n be ? ToNumber(x).
  2. If n is not finite or n is either +0𝔽 or -0𝔽, return n.
  3. If n < 1𝔽 and n > +0𝔽, return +0𝔽.
  4. If n < -0𝔽 and n > -1𝔽, return -0𝔽.
  5. Return the integral Number nearest n in the direction of +0𝔽.

21.4 Date Objects

21.4.1 Overview of Date Objects and Definitions of Abstract Operations

The following abstract operations operate on time values (defined in 21.4.1.1). Note that, in every case, if any argument to one of these functions is NaN, the result will be NaN.

21.4.1.1 Time Values and Time Range

Time measurement in ECMAScript is analogous to time measurement in POSIX, in particular sharing definition in terms of the proleptic Gregorian calendar, an epoch of midnight at the beginning of 1 January 1970 UTC, and an accounting of every day as comprising exactly 86,400 seconds (each of which is 1000 milliseconds long).

An ECMAScript time value is a Number, either a finite integral Number representing an instant in time to millisecond precision or NaN representing no specific instant. A time value that is a multiple of 24 × 60 × 60 × 1000 = 86,400,000 (i.e., is 86,400,000 × d for some integer d) represents the instant at the start of the UTC day that follows the epoch by d whole UTC days (preceding the epoch for negative d). Every other finite time value t is defined relative to the greatest preceding time value s that is such a multiple, and represents the instant that occurs within the same UTC day as s but follows it by (t - s) milliseconds.

Time values do not account for UTC leap seconds—there are no time values representing instants within positive leap seconds, and there are time values representing instants removed from the UTC timeline by negative leap seconds. However, the definition of time values nonetheless yields piecewise alignment with UTC, with discontinuities only at leap second boundaries and zero difference outside of leap seconds.

A Number can exactly represent all integers from -9,007,199,254,740,992 to 9,007,199,254,740,992 (21.1.2.8 and 21.1.2.6). A time value supports a slightly smaller range of -8,640,000,000,000,000 to 8,640,000,000,000,000 milliseconds. This yields a supported time value range of exactly -100,000,000 days to 100,000,000 days relative to midnight at the beginning of 1 January 1970 UTC.

The exact moment of midnight at the beginning of 1 January 1970 UTC is represented by the time value +0𝔽.

Note

In the proleptic Gregorian calendar, leap years are precisely those which are both divisible by 4 and either divisible by 400 or not divisible by 100.

The 400 year cycle of the proleptic Gregorian calendar contains 97 leap years. This yields an average of 365.2425 days per year, which is 31,556,952,000 milliseconds. Therefore, the maximum range a Number could represent exactly with millisecond precision is approximately -285,426 to 285,426 years relative to 1970. The smaller range supported by a time value as specified in this section is approximately -273,790 to 273,790 years relative to 1970.

21.4.1.2 Time-related Constants

These constants are referenced by algorithms in the following sections.

HoursPerDay = 24
MinutesPerHour = 60
SecondsPerMinute = 60
msPerSecond = 1000𝔽
msPerMinute = 60000𝔽 = msPerSecond × 𝔽(SecondsPerMinute)
msPerHour = 3600000𝔽 = msPerMinute × 𝔽(MinutesPerHour)
msPerDay = 86400000𝔽 = msPerHour × 𝔽(HoursPerDay)

21.4.1.3 Day ( t )

The abstract operation Day takes argument t (a finite time value) and returns an integral Number. It returns the day number of the day in which t falls. It performs the following steps when called:

  1. Return 𝔽(floor((t / msPerDay))).

21.4.1.4 TimeWithinDay ( t )

The abstract operation TimeWithinDay takes argument t (a finite time value) and returns an integral Number in the interval from +0𝔽 (inclusive) to msPerDay (exclusive). It returns the number of milliseconds since the start of the day in which t falls. It performs the following steps when called:

  1. Return 𝔽((t) modulo (msPerDay)).

21.4.1.5 DaysInYear ( y )

The abstract operation DaysInYear takes argument y (an integral Number) and returns 365𝔽 or 366𝔽. It returns the number of days in year y. Leap years have 366 days; all other years have 365. It performs the following steps when called:

  1. Let ry be (y).
  2. If (ry modulo 400) = 0, return 366𝔽.
  3. If (ry modulo 100) = 0, return 365𝔽.
  4. If (ry modulo 4) = 0, return 366𝔽.
  5. Return 365𝔽.

21.4.1.6 DayFromYear ( y )

The abstract operation DayFromYear takes argument y (an integral Number) and returns an integral Number. It returns the day number of the first day of year y. It performs the following steps when called:

  1. Let ry be (y).
  2. NOTE: In the following steps, numYears1, numYears4, numYears100, and numYears400 represent the number of years divisible by 1, 4, 100, and 400, respectively, that occur between the epoch and the start of year y. The number is negative if y is before the epoch.
  3. Let numYears1 be (ry - 1970).
  4. Let numYears4 be floor((ry - 1969) / 4).
  5. Let numYears100 be floor((ry - 1901) / 100).
  6. Let numYears400 be floor((ry - 1601) / 400).
  7. Return 𝔽(365 × numYears1 + numYears4 - numYears100 + numYears400).

21.4.1.7 TimeFromYear ( y )

The abstract operation TimeFromYear takes argument y (an integral Number) and returns a time value. It returns the time value of the start of year y. It performs the following steps when called:

  1. Return msPerDay × DayFromYear(y).

21.4.1.8 YearFromTime ( t )

The abstract operation YearFromTime takes argument t (a finite time value) and returns an integral Number. It returns the year in which t falls. It performs the following steps when called:

  1. Return the largest integral Number y (closest to +∞) such that TimeFromYear(y) ≤ t.

21.4.1.9 DayWithinYear ( t )

The abstract operation DayWithinYear takes argument t (a finite time value) and returns an integral Number in the inclusive interval from +0𝔽 to 365𝔽. It performs the following steps when called:

  1. Return Day(t) - DayFromYear(YearFromTime(t)).

21.4.1.10 InLeapYear ( t )

The abstract operation InLeapYear takes argument t (a finite time value) and returns +0𝔽 or 1𝔽. It returns 1𝔽 if t is within a leap year and +0𝔽 otherwise. It performs the following steps when called:

  1. If DaysInYear(YearFromTime(t)) is 366𝔽, return 1𝔽; else return +0𝔽.

21.4.1.11 MonthFromTime ( t )

The abstract operation MonthFromTime takes argument t (a finite time value) and returns an integral Number in the inclusive interval from +0𝔽 to 11𝔽. It returns a Number identifying the month in which t falls. A month value of +0𝔽 specifies January; 1𝔽 specifies February; 2𝔽 specifies March; 3𝔽 specifies April; 4𝔽 specifies May; 5𝔽 specifies June; 6𝔽 specifies July; 7𝔽 specifies August; 8𝔽 specifies September; 9𝔽 specifies October; 10𝔽 specifies November; and 11𝔽 specifies December. Note that MonthFromTime(+0𝔽) = +0𝔽, corresponding to Thursday, 1 January 1970. It performs the following steps when called:

  1. Let inLeapYear be InLeapYear(t).
  2. Let dayWithinYear be DayWithinYear(t).
  3. If dayWithinYear < 31𝔽, return +0𝔽.
  4. If dayWithinYear < 59𝔽 + inLeapYear, return 1𝔽.
  5. If dayWithinYear < 90𝔽 + inLeapYear, return 2𝔽.
  6. If dayWithinYear < 120𝔽 + inLeapYear, return 3𝔽.
  7. If dayWithinYear < 151𝔽 + inLeapYear, return 4𝔽.
  8. If dayWithinYear < 181𝔽 + inLeapYear, return 5𝔽.
  9. If dayWithinYear < 212𝔽 + inLeapYear, return 6𝔽.
  10. If dayWithinYear < 243𝔽 + inLeapYear, return 7𝔽.
  11. If dayWithinYear < 273𝔽 + inLeapYear, return 8𝔽.
  12. If dayWithinYear < 304𝔽 + inLeapYear, return 9𝔽.
  13. If dayWithinYear < 334𝔽 + inLeapYear, return 10𝔽.
  14. Assert: dayWithinYear < 365𝔽 + inLeapYear.
  15. Return 11𝔽.

21.4.1.12 DateFromTime ( t )

The abstract operation DateFromTime takes argument t (a finite time value) and returns an integral Number in the inclusive interval from 1𝔽 to 31𝔽. It returns the day of the month in which t falls. It performs the following steps when called:

  1. Let inLeapYear be InLeapYear(t).
  2. Let dayWithinYear be DayWithinYear(t).
  3. Let month be MonthFromTime(t).
  4. If month is +0𝔽, return dayWithinYear + 1𝔽.
  5. If month is 1𝔽, return dayWithinYear - 30𝔽.
  6. If month is 2𝔽, return dayWithinYear - 58𝔽 - inLeapYear.
  7. If month is 3𝔽, return dayWithinYear - 89𝔽 - inLeapYear.
  8. If month is 4𝔽, return dayWithinYear - 119𝔽 - inLeapYear.
  9. If month is 5𝔽, return dayWithinYear - 150𝔽 - inLeapYear.
  10. If month is 6𝔽, return dayWithinYear - 180𝔽 - inLeapYear.
  11. If month is 7𝔽, return dayWithinYear - 211𝔽 - inLeapYear.
  12. If month is 8𝔽, return dayWithinYear - 242𝔽 - inLeapYear.
  13. If month is 9𝔽, return dayWithinYear - 272𝔽 - inLeapYear.
  14. If month is 10𝔽, return dayWithinYear - 303𝔽 - inLeapYear.
  15. Assert: month is 11𝔽.
  16. Return dayWithinYear - 333𝔽 - inLeapYear.

21.4.1.13 WeekDay ( t )

The abstract operation WeekDay takes argument t (a finite time value) and returns an integral Number in the inclusive interval from +0𝔽 to 6𝔽. It returns a Number identifying the day of the week in which t falls. A weekday value of +0𝔽 specifies Sunday; 1𝔽 specifies Monday; 2𝔽 specifies Tuesday; 3𝔽 specifies Wednesday; 4𝔽 specifies Thursday; 5𝔽 specifies Friday; and 6𝔽 specifies Saturday. Note that WeekDay(+0𝔽) = 4𝔽, corresponding to Thursday, 1 January 1970. It performs the following steps when called:

  1. Return 𝔽((Day(t) + 4𝔽) modulo 7).

21.4.1.14 HourFromTime ( t )

The abstract operation HourFromTime takes argument t (a finite time value) and returns an integral Number in the inclusive interval from +0𝔽 to 23𝔽. It returns the hour of the day in which t falls. It performs the following steps when called:

  1. Return 𝔽(floor((t / msPerHour)) modulo HoursPerDay).

21.4.1.15 MinFromTime ( t )

The abstract operation MinFromTime takes argument t (a finite time value) and returns an integral Number in the inclusive interval from +0𝔽 to 59𝔽. It returns the minute of the hour in which t falls. It performs the following steps when called:

  1. Return 𝔽(floor((t / msPerMinute)) modulo MinutesPerHour).

21.4.1.16 SecFromTime ( t )

The abstract operation SecFromTime takes argument t (a finite time value) and returns an integral Number in the inclusive interval from +0𝔽 to 59𝔽. It returns the second of the minute in which t falls. It performs the following steps when called:

  1. Return 𝔽(floor((t / msPerSecond)) modulo SecondsPerMinute).

21.4.1.17 msFromTime ( t )

The abstract operation msFromTime takes argument t (a finite time value) and returns an integral Number in the inclusive interval from +0𝔽 to 999𝔽. It returns the millisecond of the second in which t falls. It performs the following steps when called:

  1. Return 𝔽((t) modulo (msPerSecond)).

21.4.1.18 GetUTCEpochNanoseconds ( year, month, day, hour, minute, second, millisecond, microsecond, nanosecond )

The abstract operation GetUTCEpochNanoseconds takes arguments year (an integer), month (an integer in the inclusive interval from 1 to 12), day (an integer in the inclusive interval from 1 to 31), hour (an integer in the inclusive interval from 0 to 23), minute (an integer in the inclusive interval from 0 to 59), second (an integer in the inclusive interval from 0 to 59), millisecond (an integer in the inclusive interval from 0 to 999), microsecond (an integer in the inclusive interval from 0 to 999), and nanosecond (an integer in the inclusive interval from 0 to 999) and returns a BigInt. The returned value represents a number of nanoseconds since the epoch that corresponds to the given ISO 8601 calendar date and wall-clock time in UTC. It performs the following steps when called:

  1. Let date be MakeDay(𝔽(year), 𝔽(month - 1), 𝔽(day)).
  2. Let time be MakeTime(𝔽(hour), 𝔽(minute), 𝔽(second), 𝔽(millisecond)).
  3. Let ms be MakeDate(date, time).
  4. Assert: ms is an integral Number.
  5. Return ((ms) × 106 + microsecond × 103 + nanosecond).

21.4.1.19 Time Zone Identifiers

Time zones in ECMAScript are represented by time zone identifiers, which are Strings composed entirely of code units in the inclusive interval from 0x0000 to 0x007F. Time zones supported by an ECMAScript implementation may be available named time zones, represented by the [[Identifier]] field of the Time Zone Identifier Records returned by AvailableNamedTimeZoneIdentifiers, or offset time zones, represented by Strings for which IsTimeZoneOffsetString returns true.

A primary time zone identifier is the preferred identifier for an available named time zone. A non-primary time zone identifier is an identifier for an available named time zone that is not a primary time zone identifier. An available named time zone identifier is either a primary time zone identifier or a non-primary time zone identifier. Each available named time zone identifier is associated with exactly one available named time zone. Each available named time zone is associated with exactly one primary time zone identifier and zero or more non-primary time zone identifiers.

ECMAScript implementations must support an available named time zone with the identifier "UTC", which must be the primary time zone identifier for the UTC time zone. In addition, implementations may support any number of other available named time zones.

Implementations that follow the requirements for time zones as described in the ECMA-402 Internationalization API specification are called time zone aware. Time zone aware implementations must support available named time zones corresponding to the Zone and Link names of the IANA Time Zone Database, and only such names. In time zone aware implementations, a primary time zone identifier is a Zone name, and a non-primary time zone identifier is a Link name, respectively, in the IANA Time Zone Database except as specifically overridden by AvailableNamedTimeZoneIdentifiers as specified in the ECMA-402 specification. Implementations that do not support the entire IANA Time Zone Database are still recommended to use IANA Time Zone Database names as identifiers to represent time zones.

21.4.1.20 GetNamedTimeZoneEpochNanoseconds ( timeZoneIdentifier, year, month, day, hour, minute, second, millisecond, microsecond, nanosecond )

The implementation-defined abstract operation GetNamedTimeZoneEpochNanoseconds takes arguments timeZoneIdentifier (a String), year (an integer), month (an integer in the inclusive interval from 1 to 12), day (an integer in the inclusive interval from 1 to 31), hour (an integer in the inclusive interval from 0 to 23), minute (an integer in the inclusive interval from 0 to 59), second (an integer in the inclusive interval from 0 to 59), millisecond (an integer in the inclusive interval from 0 to 999), microsecond (an integer in the inclusive interval from 0 to 999), and nanosecond (an integer in the inclusive interval from 0 to 999) and returns a List of BigInts. Each value in the returned List represents a number of nanoseconds since the epoch that corresponds to the given ISO 8601 calendar date and wall-clock time in the named time zone identified by timeZoneIdentifier.

When the input represents a local time occurring more than once because of a negative time zone transition (e.g. when daylight saving time ends or the time zone offset is decreased due to a time zone rule change), the returned List will have more than one element and will be sorted by ascending numerical value. When the input represents a local time skipped because of a positive time zone transition (e.g. when daylight saving time begins or the time zone offset is increased due to a time zone rule change), the returned List will be empty. Otherwise, the returned List will have one element.

The default implementation of GetNamedTimeZoneEpochNanoseconds, to be used for ECMAScript implementations that do not include local political rules for any time zones, performs the following steps when called:

  1. Assert: timeZoneIdentifier is "UTC".
  2. Let epochNanoseconds be GetUTCEpochNanoseconds(year, month, day, hour, minute, second, millisecond, microsecond, nanosecond).
  3. Return « epochNanoseconds ».
Note

It is required for time zone aware implementations (and recommended for all others) to use the time zone information of the IANA Time Zone Database https://www.iana.org/time-zones/.

1:30 AM on 5 November 2017 in America/New_York is repeated twice, so GetNamedTimeZoneEpochNanoseconds("America/New_York", 2017, 11, 5, 1, 30, 0, 0, 0, 0) would return a List of length 2 in which the first element represents 05:30 UTC (corresponding with 01:30 US Eastern Daylight Time at UTC offset -04:00) and the second element represents 06:30 UTC (corresponding with 01:30 US Eastern Standard Time at UTC offset -05:00).

2:30 AM on 12 March 2017 in America/New_York does not exist, so GetNamedTimeZoneEpochNanoseconds("America/New_York", 2017, 3, 12, 2, 30, 0, 0, 0, 0) would return an empty List.

21.4.1.21 GetNamedTimeZoneOffsetNanoseconds ( timeZoneIdentifier, epochNanoseconds )

The implementation-defined abstract operation GetNamedTimeZoneOffsetNanoseconds takes arguments timeZoneIdentifier (a String) and epochNanoseconds (a BigInt) and returns an integer.

The returned integer represents the offset from UTC of the named time zone identified by timeZoneIdentifier, at the instant corresponding with epochNanoseconds relative to the epoch, both in nanoseconds.

The default implementation of GetNamedTimeZoneOffsetNanoseconds, to be used for ECMAScript implementations that do not include local political rules for any time zones, performs the following steps when called:

  1. Assert: timeZoneIdentifier is "UTC".
  2. Return 0.
Note

Time zone offset values may be positive or negative.

21.4.1.22 Time Zone Identifier Record

A Time Zone Identifier Record is a Record used to describe an available named time zone identifier and its corresponding primary time zone identifier.

Time Zone Identifier Records have the fields listed in Table 64.

Table 64: Time Zone Identifier Record Fields
Field Name Value Meaning
[[Identifier]] a String An available named time zone identifier that is supported by the implementation.
[[PrimaryIdentifier]] a String The primary time zone identifier that [[Identifier]] resolves to.
Note

If [[Identifier]] is a primary time zone identifier, then [[Identifier]] is [[PrimaryIdentifier]].

21.4.1.23 AvailableNamedTimeZoneIdentifiers ( )

The implementation-defined abstract operation AvailableNamedTimeZoneIdentifiers takes no arguments and returns a List of Time Zone Identifier Records. Its result describes all available named time zone identifiers in this implementation, as well as the primary time zone identifier corresponding to each available named time zone identifier. The List is ordered according to the [[Identifier]] field of each Time Zone Identifier Record.

Time zone aware implementations, including all implementations that implement the ECMA-402 Internationalization API, must implement the AvailableNamedTimeZoneIdentifiers abstract operation as specified in the ECMA-402 specification. For implementations that are not time zone aware, AvailableNamedTimeZoneIdentifiers performs the following steps when called:

  1. If the implementation does not include local political rules for any time zones, then
    1. Return « the Time Zone Identifier Record { [[Identifier]]: "UTC", [[PrimaryIdentifier]]: "UTC" } ».
  2. Let identifiers be the List of unique available named time zone identifiers, sorted according to lexicographic code unit order.
  3. Let result be a new empty List.
  4. For each element identifier of identifiers, do
    1. Let primary be identifier.
    2. If identifier is a non-primary time zone identifier in this implementation and identifier is not "UTC", then
      1. Set primary to the primary time zone identifier associated with identifier.
      2. NOTE: An implementation may need to resolve identifier iteratively to obtain the primary time zone identifier.
    3. Let record be the Time Zone Identifier Record { [[Identifier]]: identifier, [[PrimaryIdentifier]]: primary }.
    4. Append record to result.
  5. Assert: result contains a Time Zone Identifier Record r such that r.[[Identifier]] is "UTC" and r.[[PrimaryIdentifier]] is "UTC".
  6. Return result.

21.4.1.24 SystemTimeZoneIdentifier ( )

The implementation-defined abstract operation SystemTimeZoneIdentifier takes no arguments and returns a String. It returns a String representing the host environment's current time zone, which is either a String representing a UTC offset for which IsTimeZoneOffsetString returns true, or a primary time zone identifier. It performs the following steps when called:

  1. If the implementation only supports the UTC time zone, return "UTC".
  2. Let systemTimeZoneString be the String representing the host environment's current time zone, either a primary time zone identifier or an offset time zone identifier.
  3. Return systemTimeZoneString.
Note

To ensure the level of functionality that implementations commonly provide in the methods of the Date object, it is recommended that SystemTimeZoneIdentifier return an IANA time zone name corresponding to the host environment's time zone setting, if such a thing exists. GetNamedTimeZoneEpochNanoseconds and GetNamedTimeZoneOffsetNanoseconds must reflect the local political rules for standard time and daylight saving time in that time zone, if such rules exist.

For example, if the host environment is a browser on a system where the user has chosen US Eastern Time as their time zone, SystemTimeZoneIdentifier returns "America/New_York".

21.4.1.25 LocalTime ( t )

The abstract operation LocalTime takes argument t (a finite time value) and returns an integral Number. It converts t from UTC to local time. The local political rules for standard time and daylight saving time in effect at t should be used to determine the result in the way specified in this section. It performs the following steps when called:

  1. Let systemTimeZoneIdentifier be SystemTimeZoneIdentifier().
  2. If IsTimeZoneOffsetString(systemTimeZoneIdentifier) is true, then
    1. Let offsetNs be ParseTimeZoneOffsetString(systemTimeZoneIdentifier).
  3. Else,
    1. Let offsetNs be GetNamedTimeZoneOffsetNanoseconds(systemTimeZoneIdentifier, ((t) × 106)).
  4. Let offsetMs be truncate(offsetNs / 106).
  5. Return t + 𝔽(offsetMs).
Note 1

If political rules for the local time t are not available within the implementation, the result is t because SystemTimeZoneIdentifier returns "UTC" and GetNamedTimeZoneOffsetNanoseconds returns 0.

Note 2

It is required for time zone aware implementations (and recommended for all others) to use the time zone information of the IANA Time Zone Database https://www.iana.org/time-zones/.

Note 3

Two different input time values tUTC are converted to the same local time tlocal at a negative time zone transition when there are repeated times (e.g. the daylight saving time ends or the time zone adjustment is decreased.).

LocalTime(UTC(tlocal)) is not necessarily always equal to tlocal. Correspondingly, UTC(LocalTime(tUTC)) is not necessarily always equal to tUTC.

21.4.1.26 UTC ( t )

The abstract operation UTC takes argument t (a Number) and returns a time value. It converts t from local time to a UTC time value. The local political rules for standard time and daylight saving time in effect at t should be used to determine the result in the way specified in this section. It performs the following steps when called:

  1. If t is not finite, return NaN.
  2. Let systemTimeZoneIdentifier be SystemTimeZoneIdentifier().
  3. If IsTimeZoneOffsetString(systemTimeZoneIdentifier) is true, then
    1. Let offsetNs be ParseTimeZoneOffsetString(systemTimeZoneIdentifier).
  4. Else,
    1. Let possibleInstants be GetNamedTimeZoneEpochNanoseconds(systemTimeZoneIdentifier, (YearFromTime(t)), (MonthFromTime(t)) + 1, (DateFromTime(t)), (HourFromTime(t)), (MinFromTime(t)), (SecFromTime(t)), (msFromTime(t)), 0, 0).
    2. NOTE: The following steps ensure that when t represents local time repeating multiple times at a negative time zone transition (e.g. when the daylight saving time ends or the time zone offset is decreased due to a time zone rule change) or skipped local time at a positive time zone transition (e.g. when the daylight saving time starts or the time zone offset is increased due to a time zone rule change), t is interpreted using the time zone offset before the transition.
    3. If possibleInstants is not empty, then
      1. Let disambiguatedInstant be possibleInstants[0].
    4. Else,
      1. NOTE: t represents a local time skipped at a positive time zone transition (e.g. due to daylight saving time starting or a time zone rule change increasing the UTC offset).
      2. Let possibleInstantsBefore be GetNamedTimeZoneEpochNanoseconds(systemTimeZoneIdentifier, (YearFromTime(tBefore)), (MonthFromTime(tBefore)) + 1, (DateFromTime(tBefore)), (HourFromTime(tBefore)), (MinFromTime(tBefore)), (SecFromTime(tBefore)), (msFromTime(tBefore)), 0, 0), where tBefore is the largest integral Number < t for which possibleInstantsBefore is not empty (i.e., tBefore represents the last local time before the transition).
      3. Let disambiguatedInstant be the last element of possibleInstantsBefore.
    5. Let offsetNs be GetNamedTimeZoneOffsetNanoseconds(systemTimeZoneIdentifier, disambiguatedInstant).
  5. Let offsetMs be truncate(offsetNs / 106).
  6. Return t - 𝔽(offsetMs).

Input t is nominally a time value but may be any Number value. The algorithm must not limit t to the time value range, so that inputs corresponding with a boundary of the time value range can be supported regardless of local UTC offset. For example, the maximum time value is 8.64 × 1015, corresponding with "+275760-09-13T00:00:00Z". In an environment where the local time zone offset is ahead of UTC by 1 hour at that instant, it is represented by the larger input of 8.64 × 1015 + 3.6 × 106, corresponding with "+275760-09-13T01:00:00+01:00".

If political rules for the local time t are not available within the implementation, the result is t because SystemTimeZoneIdentifier returns "UTC" and GetNamedTimeZoneOffsetNanoseconds returns 0.

Note 1

It is required for time zone aware implementations (and recommended for all others) to use the time zone information of the IANA Time Zone Database https://www.iana.org/time-zones/.

1:30 AM on 5 November 2017 in America/New_York is repeated twice (fall backward), but it must be interpreted as 1:30 AM UTC-04 instead of 1:30 AM UTC-05. In UTC(TimeClip(MakeDate(MakeDay(2017, 10, 5), MakeTime(1, 30, 0, 0)))), the value of offsetMs is -4 × msPerHour.

2:30 AM on 12 March 2017 in America/New_York does not exist, but it must be interpreted as 2:30 AM UTC-05 (equivalent to 3:30 AM UTC-04). In UTC(TimeClip(MakeDate(MakeDay(2017, 2, 12), MakeTime(2, 30, 0, 0)))), the value of offsetMs is -5 × msPerHour.

Note 2

UTC(LocalTime(tUTC)) is not necessarily always equal to tUTC. Correspondingly, LocalTime(UTC(tlocal)) is not necessarily always equal to tlocal.

21.4.1.27 MakeTime ( hour, min, sec, ms )

The abstract operation MakeTime takes arguments hour (a Number), min (a Number), sec (a Number), and ms (a Number) and returns a Number. It calculates a number of milliseconds. It performs the following steps when called:

  1. If hour is not finite, min is not finite, sec is not finite, or ms is not finite, return NaN.
  2. Let h be 𝔽(! ToIntegerOrInfinity(hour)).
  3. Let m be 𝔽(! ToIntegerOrInfinity(min)).
  4. Let s be 𝔽(! ToIntegerOrInfinity(sec)).
  5. Let milli be 𝔽(! ToIntegerOrInfinity(ms)).
  6. Return ((h × msPerHour + m × msPerMinute) + s × msPerSecond) + milli.
Note

The arithmetic in MakeTime is floating-point arithmetic, which is not associative, so the operations must be performed in the correct order.

21.4.1.28 MakeDay ( year, month, date )

The abstract operation MakeDay takes arguments year (a Number), month (a Number), and date (a Number) and returns a Number. It calculates a number of days. It performs the following steps when called:

  1. If year is not finite, month is not finite, or date is not finite, return NaN.
  2. Let y be 𝔽(! ToIntegerOrInfinity(year)).
  3. Let m be 𝔽(! ToIntegerOrInfinity(month)).
  4. Let dt be 𝔽(! ToIntegerOrInfinity(date)).
  5. Let ym be y + 𝔽(floor((m) / 12)).
  6. If ym is not finite, return NaN.
  7. Let mn be 𝔽((m) modulo 12).
  8. Find a finite time value t such that YearFromTime(t) is ym, MonthFromTime(t) is mn, and DateFromTime(t) is 1𝔽; but if this is not possible (because some argument is out of range), return NaN.
  9. Return Day(t) + dt - 1𝔽.

21.4.1.29 MakeDate ( day, time )

The abstract operation MakeDate takes arguments day (a Number) and time (a Number) and returns a Number. It calculates a number of milliseconds. It performs the following steps when called:

  1. If day is not finite or time is not finite, return NaN.
  2. Let tv be day × msPerDay + time.
  3. If tv is not finite, return NaN.
  4. Return tv.

21.4.1.30 MakeFullYear ( year )

The abstract operation MakeFullYear takes argument year (a Number) and returns an integral Number or NaN. It returns the full year associated with the integer part of year, interpreting any value in the inclusive interval from 0 to 99 as a count of years since the start of 1900. For alignment with the proleptic Gregorian calendar, "full year" is defined as the signed count of complete years since the start of year 0 (1 B.C.). It performs the following steps when called:

  1. If year is NaN, return NaN.
  2. Let truncated be ! ToIntegerOrInfinity(year).
  3. If truncated is in the inclusive interval from 0 to 99, return 1900𝔽 + 𝔽(truncated).
  4. Return 𝔽(truncated).

21.4.1.31 TimeClip ( time )

The abstract operation TimeClip takes argument time (a Number) and returns a Number. It calculates a number of milliseconds. It performs the following steps when called:

  1. If time is not finite, return NaN.
  2. If abs((time)) > 8.64 × 1015, return NaN.
  3. Return 𝔽(! ToIntegerOrInfinity(time)).

21.4.1.32 Date Time String Format

ECMAScript defines a string interchange format for date-times based upon a simplification of the ISO 8601 calendar date extended format. The format is as follows: YYYY-MM-DDTHH:mm:ss.sssZ

Where the elements are as follows:

YYYY is the year in the proleptic Gregorian calendar as four decimal digits from 0000 to 9999, or as an expanded year of "+" or "-" followed by six decimal digits.
- "-" (hyphen) appears literally twice in the string.
MM is the month of the year as two decimal digits from 01 (January) to 12 (December).
DD is the day of the month as two decimal digits from 01 to 31.
T "T" appears literally in the string, to indicate the beginning of the time element.
HH is the number of complete hours that have passed since midnight as two decimal digits from 00 to 24.
: ":" (colon) appears literally twice in the string.
mm is the number of complete minutes since the start of the hour as two decimal digits from 00 to 59.
ss is the number of complete seconds since the start of the minute as two decimal digits from 00 to 59.
. "." (dot) appears literally in the string.
sss is the number of complete milliseconds since the start of the second as three decimal digits.
Z is the UTC offset representation specified as "Z" (for UTC with no offset) or as either "+" or "-" followed by a time expression HH:mm (a subset of the time zone offset string format for indicating local time ahead of or behind UTC, respectively)

This format includes date-only forms:

YYYY
YYYY-MM
YYYY-MM-DD
        

It also includes “date-time” forms that consist of one of the above date-only forms immediately followed by one of the following time forms with an optional UTC offset representation appended:

THH:mm
THH:mm:ss
THH:mm:ss.sss
        

A string containing out-of-bounds or nonconforming elements is not a valid instance of this format.

Note 1

As every day both starts and ends with midnight, the two notations 00:00 and 24:00 are available to distinguish the two midnights that can be associated with one date. This means that the following two notations refer to exactly the same point in time: 1995-02-04T24:00 and 1995-02-05T00:00. This interpretation of the latter form as "end of a calendar day" is consistent with ISO 8601, even though that specification reserves it for describing time intervals and does not permit it within representations of single points in time.

Note 2

There exists no international standard that specifies abbreviations for civil time zones like CET, EST, etc. and sometimes the same abbreviation is even used for two very different time zones. For this reason, both ISO 8601 and this format specify numeric representations of time zone offsets.

21.4.1.32.1 Expanded Years

Covering the full time value range of approximately 273,790 years forward or backward from 1 January 1970 (21.4.1.1) requires representing years before 0 or after 9999. ISO 8601 permits expansion of the year representation, but only by mutual agreement of the partners in information interchange. In the simplified ECMAScript format, such an expanded year representation shall have 6 digits and is always prefixed with a + or - sign. The year 0 is considered positive and must be prefixed with a + sign. The representation of the year 0 as -000000 is invalid. Strings matching the Date Time String Format with expanded years representing instants in time outside the range of a time value are treated as unrecognizable by Date.parse and cause that function to return NaN without falling back to implementation-specific behaviour or heuristics.

Note

Examples of date-time values with expanded years:

-271821-04-20T00:00:00Z 271822 B.C.
-000001-01-01T00:00:00Z 2 B.C.
+000000-01-01T00:00:00Z 1 B.C.
+000001-01-01T00:00:00Z 1 A.D.
+001970-01-01T00:00:00Z 1970 A.D.
+002009-12-15T00:00:00Z 2009 A.D.
+275760-09-13T00:00:00Z 275760 A.D.

21.4.1.33 Time Zone Offset String Format

ECMAScript defines a string interchange format for UTC offsets, derived from ISO 8601. The format is described by the following grammar.

Syntax

UTCOffset ::: ASCIISign Hour ASCIISign Hour HourSubcomponents[+Extended] ASCIISign Hour HourSubcomponents[~Extended] ASCIISign ::: one of + - Hour ::: 0 DecimalDigit 1 DecimalDigit 20 21 22 23 HourSubcomponents[Extended] ::: TimeSeparator[?Extended] MinuteSecond TimeSeparator[?Extended] MinuteSecond TimeSeparator[?Extended] MinuteSecond TemporalDecimalFractionopt TimeSeparator[Extended] ::: [+Extended] : [~Extended] [empty] MinuteSecond ::: 0 DecimalDigit 1 DecimalDigit 2 DecimalDigit 3 DecimalDigit 4 DecimalDigit 5 DecimalDigit TemporalDecimalFraction ::: TemporalDecimalSeparator DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator ::: one of . ,

21.4.1.33.1 IsTimeZoneOffsetString ( offsetString )

The abstract operation IsTimeZoneOffsetString takes argument offsetString (a String) and returns a Boolean. The return value indicates whether offsetString conforms to the grammar given by UTCOffset. It performs the following steps when called:

  1. Let parseResult be ParseText(offsetString, UTCOffset).
  2. If parseResult is a List of errors, return false.
  3. Return true.

21.4.1.33.2 ParseTimeZoneOffsetString ( offsetString )

The abstract operation ParseTimeZoneOffsetString takes argument offsetString (a String) and returns an integer. The return value is the UTC offset, as a number of nanoseconds, that corresponds to the String offsetString. It performs the following steps when called:

  1. Let parseResult be ParseText(offsetString, UTCOffset).
  2. Assert: parseResult is not a List of errors.
  3. Assert: parseResult contains a ASCIISign Parse Node.
  4. Let parsedSign be the source text matched by the ASCIISign Parse Node contained within parseResult.
  5. If parsedSign is the single code point U+002D (HYPHEN-MINUS), then
    1. Let sign be -1.
  6. Else,
    1. Let sign be 1.
  7. NOTE: Applications of StringToNumber below do not lose precision, since each of the parsed values is guaranteed to be a sufficiently short string of decimal digits.
  8. Assert: parseResult contains an Hour Parse Node.
  9. Let parsedHours be the source text matched by the Hour Parse Node contained within parseResult.
  10. Let hours be (StringToNumber(CodePointsToString(parsedHours))).
  11. If parseResult does not contain a MinuteSecond Parse Node, then
    1. Let minutes be 0.
  12. Else,
    1. Let parsedMinutes be the source text matched by the first MinuteSecond Parse Node contained within parseResult.
    2. Let minutes be (StringToNumber(CodePointsToString(parsedMinutes))).
  13. If parseResult does not contain two MinuteSecond Parse Nodes, then
    1. Let seconds be 0.
  14. Else,
    1. Let parsedSeconds be the source text matched by the second MinuteSecond Parse Node contained within parseResult.
    2. Let seconds be (StringToNumber(CodePointsToString(parsedSeconds))).
  15. If parseResult does not contain a TemporalDecimalFraction Parse Node, then
    1. Let nanoseconds be 0.
  16. Else,
    1. Let parsedFraction be the source text matched by the TemporalDecimalFraction Parse Node contained within parseResult.
    2. Let fraction be the string-concatenation of CodePointsToString(parsedFraction) and "000000000".
    3. Let nanosecondsString be the substring of fraction from 1 to 10.
    4. Let nanoseconds be (StringToNumber(nanosecondsString)).
  17. Return sign × (((hours × 60 + minutes) × 60 + seconds) × 109 + nanoseconds).

21.4.2 The Date Constructor

The Date constructor:

  • is %Date%.
  • is the initial value of the "Date" property of the global object.
  • creates and initializes a new Date when called as a constructor.
  • returns a String representing the current time (UTC) when called as a function rather than as a constructor.
  • is a function whose behaviour differs based upon the number and types of its arguments.
  • may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified Date behaviour must include a super call to the Date constructor to create and initialize the subclass instance with a [[DateValue]] internal slot.

21.4.2.1 Date ( ...values )

This function performs the following steps when called:

  1. If NewTarget is undefined, then
    1. Let now be the time value (UTC) identifying the current time.
    2. Return ToDateString(now).
  2. Let numberOfArgs be the number of elements in values.
  3. If numberOfArgs = 0, then
    1. Let dv be the time value (UTC) identifying the current time.
  4. Else if numberOfArgs = 1, then
    1. Let value be values[0].
    2. If value is an Object and value has a [[DateValue]] internal slot, then
      1. Let tv be value.[[DateValue]].
    3. Else,
      1. Let v be ? ToPrimitive(value).
      2. If v is a String, then
        1. Assert: The next step never returns an abrupt completion because v is a String.
        2. Let tv be the result of parsing v as a date, in exactly the same manner as for the parse method (21.4.3.2).
      3. Else,
        1. Let tv be ? ToNumber(v).
    4. Let dv be TimeClip(tv).
  5. Else,
    1. Assert: numberOfArgs ≥ 2.
    2. Let y be ? ToNumber(values[0]).
    3. Let m be ? ToNumber(values[1]).
    4. If numberOfArgs > 2, let dt be ? ToNumber(values[2]); else let dt be 1𝔽.
    5. If numberOfArgs > 3, let h be ? ToNumber(values[3]); else let h be +0𝔽.
    6. If numberOfArgs > 4, let min be ? ToNumber(values[4]); else let min be +0𝔽.
    7. If numberOfArgs > 5, let s be ? ToNumber(values[5]); else let s be +0𝔽.
    8. If numberOfArgs > 6, let milli be ? ToNumber(values[6]); else let milli be +0𝔽.
    9. Let yr be MakeFullYear(y).
    10. Let finalDate be MakeDate(MakeDay(yr, m, dt), MakeTime(h, min, s, milli)).
    11. Let dv be TimeClip(UTC(finalDate)).
  6. Let O be ? OrdinaryCreateFromConstructor(NewTarget, "%Date.prototype%", « [[DateValue]] »).
  7. Set O.[[DateValue]] to dv.
  8. Return O.

21.4.3 Properties of the Date Constructor

The Date constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has a "length" property whose value is 7𝔽.
  • has the following properties:

21.4.3.1 Date.now ( )

This function returns the time value designating the UTC date and time of the occurrence of the call to it.

21.4.3.2 Date.parse ( string )

This function applies the ToString operator to its argument. If ToString results in an abrupt completion the Completion Record is immediately returned. Otherwise, this function interprets the resulting String as a date and time; it returns a Number, the UTC time value corresponding to the date and time. The String may be interpreted as a local time, a UTC time, or a time in some other time zone, depending on the contents of the String. The function first attempts to parse the String according to the format described in Date Time String Format (21.4.1.32), including expanded years. If the String does not conform to that format the function may fall back to any implementation-specific heuristics or implementation-specific date formats. Strings that are unrecognizable or contain out-of-bounds format element values shall cause this function to return NaN.

If the String conforms to the Date Time String Format, substitute values take the place of absent format elements. When the MM or DD elements are absent, "01" is used. When the HH, mm, or ss elements are absent, "00" is used. When the sss element is absent, "000" is used. When the UTC offset representation is absent, date-only forms are interpreted as a UTC time and date-time forms are interpreted as a local time.

If x is any Date whose milliseconds amount is zero within a particular implementation of ECMAScript, then all of the following expressions should produce the same numeric value in that implementation, if all the properties referenced have their initial values:

x.valueOf()
Date.parse(x.toString())
Date.parse(x.toUTCString())
Date.parse(x.toISOString())

However, the expression

Date.parse(x.toLocaleString())

is not required to produce the same Number value as the preceding three expressions and, in general, the value produced by this function is implementation-defined when given any String value that does not conform to the Date Time String Format (21.4.1.32) and that could not be produced in that implementation by the toString or toUTCString method.

21.4.3.3 Date.prototype

The initial value of Date.prototype is the Date prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

21.4.3.4 Date.UTC ( year [ , month [ , date [ , hours [ , minutes [ , seconds [ , ms ] ] ] ] ] ] )

This function performs the following steps when called:

  1. Let y be ? ToNumber(year).
  2. If month is present, let m be ? ToNumber(month); else let m be +0𝔽.
  3. If date is present, let dt be ? ToNumber(date); else let dt be 1𝔽.
  4. If hours is present, let h be ? ToNumber(hours); else let h be +0𝔽.
  5. If minutes is present, let min be ? ToNumber(minutes); else let min be +0𝔽.
  6. If seconds is present, let s be ? ToNumber(seconds); else let s be +0𝔽.
  7. If ms is present, let milli be ? ToNumber(ms); else let milli be +0𝔽.
  8. Let yr be MakeFullYear(y).
  9. Return TimeClip(MakeDate(MakeDay(yr, m, dt), MakeTime(h, min, s, milli))).

The "length" property of this function is 7𝔽.

Note

This function differs from the Date constructor in two ways: it returns a time value as a Number, rather than creating a Date, and it interprets the arguments in UTC rather than as local time.

21.4.4 Properties of the Date Prototype Object

The Date prototype object:

  • is %Date.prototype%.
  • is itself an ordinary object.
  • is not a Date instance and does not have a [[DateValue]] internal slot.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.

Unless explicitly defined otherwise, the methods of the Date prototype object defined below are not generic and the this value passed to them must be an object that has a [[DateValue]] internal slot that has been initialized to a time value.

21.4.4.1 Date.prototype.constructor

The initial value of Date.prototype.constructor is %Date%.

21.4.4.2 Date.prototype.getDate ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, return NaN.
  5. Return DateFromTime(LocalTime(t)).

21.4.4.3 Date.prototype.getDay ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, return NaN.
  5. Return WeekDay(LocalTime(t)).

21.4.4.4 Date.prototype.getFullYear ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, return NaN.
  5. Return YearFromTime(LocalTime(t)).

21.4.4.5 Date.prototype.getHours ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, return NaN.
  5. Return HourFromTime(LocalTime(t)).

21.4.4.6 Date.prototype.getMilliseconds ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, return NaN.
  5. Return msFromTime(LocalTime(t)).

21.4.4.7 Date.prototype.getMinutes ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, return NaN.
  5. Return MinFromTime(LocalTime(t)).

21.4.4.8 Date.prototype.getMonth ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, return NaN.
  5. Return MonthFromTime(LocalTime(t)).

21.4.4.9 Date.prototype.getSeconds ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, return NaN.
  5. Return SecFromTime(LocalTime(t)).

21.4.4.10 Date.prototype.getTime ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Return dateObject.[[DateValue]].

21.4.4.11 Date.prototype.getTimezoneOffset ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, return NaN.
  5. Return (t - LocalTime(t)) / msPerMinute.

21.4.4.12 Date.prototype.getUTCDate ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, return NaN.
  5. Return DateFromTime(t).

21.4.4.13 Date.prototype.getUTCDay ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, return NaN.
  5. Return WeekDay(t).

21.4.4.14 Date.prototype.getUTCFullYear ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, return NaN.
  5. Return YearFromTime(t).

21.4.4.15 Date.prototype.getUTCHours ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, return NaN.
  5. Return HourFromTime(t).

21.4.4.16 Date.prototype.getUTCMilliseconds ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, return NaN.
  5. Return msFromTime(t).

21.4.4.17 Date.prototype.getUTCMinutes ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, return NaN.
  5. Return MinFromTime(t).

21.4.4.18 Date.prototype.getUTCMonth ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, return NaN.
  5. Return MonthFromTime(t).

21.4.4.19 Date.prototype.getUTCSeconds ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, return NaN.
  5. Return SecFromTime(t).

21.4.4.20 Date.prototype.setDate ( date )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. Let dt be ? ToNumber(date).
  5. If t is NaN, return NaN.
  6. Set t to LocalTime(t).
  7. Let newDate be MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), dt), TimeWithinDay(t)).
  8. Let u be TimeClip(UTC(newDate)).
  9. Set dateObject.[[DateValue]] to u.
  10. Return u.

21.4.4.21 Date.prototype.setFullYear ( year [ , month [ , date ] ] )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. Let y be ? ToNumber(year).
  5. If t is NaN, set t to +0𝔽; otherwise set t to LocalTime(t).
  6. If month is not present, let m be MonthFromTime(t); otherwise let m be ? ToNumber(month).
  7. If date is not present, let dt be DateFromTime(t); otherwise let dt be ? ToNumber(date).
  8. Let newDate be MakeDate(MakeDay(y, m, dt), TimeWithinDay(t)).
  9. Let u be TimeClip(UTC(newDate)).
  10. Set dateObject.[[DateValue]] to u.
  11. Return u.

The "length" property of this method is 3𝔽.

Note

If month is not present, this method behaves as if month was present with the value getMonth(). If date is not present, it behaves as if date was present with the value getDate().

21.4.4.22 Date.prototype.setHours ( hour [ , min [ , sec [ , ms ] ] ] )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. Let h be ? ToNumber(hour).
  5. If min is present, let m be ? ToNumber(min).
  6. If sec is present, let s be ? ToNumber(sec).
  7. If ms is present, let milli be ? ToNumber(ms).
  8. If t is NaN, return NaN.
  9. Set t to LocalTime(t).
  10. If min is not present, let m be MinFromTime(t).
  11. If sec is not present, let s be SecFromTime(t).
  12. If ms is not present, let milli be msFromTime(t).
  13. Let date be MakeDate(Day(t), MakeTime(h, m, s, milli)).
  14. Let u be TimeClip(UTC(date)).
  15. Set dateObject.[[DateValue]] to u.
  16. Return u.

The "length" property of this method is 4𝔽.

Note

If min is not present, this method behaves as if min was present with the value getMinutes(). If sec is not present, it behaves as if sec was present with the value getSeconds(). If ms is not present, it behaves as if ms was present with the value getMilliseconds().

21.4.4.23 Date.prototype.setMilliseconds ( ms )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. Set ms to ? ToNumber(ms).
  5. If t is NaN, return NaN.
  6. Set t to LocalTime(t).
  7. Let time be MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms).
  8. Let u be TimeClip(UTC(MakeDate(Day(t), time))).
  9. Set dateObject.[[DateValue]] to u.
  10. Return u.

21.4.4.24 Date.prototype.setMinutes ( min [ , sec [ , ms ] ] )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. Let m be ? ToNumber(min).
  5. If sec is present, let s be ? ToNumber(sec).
  6. If ms is present, let milli be ? ToNumber(ms).
  7. If t is NaN, return NaN.
  8. Set t to LocalTime(t).
  9. If sec is not present, let s be SecFromTime(t).
  10. If ms is not present, let milli be msFromTime(t).
  11. Let date be MakeDate(Day(t), MakeTime(HourFromTime(t), m, s, milli)).
  12. Let u be TimeClip(UTC(date)).
  13. Set dateObject.[[DateValue]] to u.
  14. Return u.

The "length" property of this method is 3𝔽.

Note

If sec is not present, this method behaves as if sec was present with the value getSeconds(). If ms is not present, this behaves as if ms was present with the value getMilliseconds().

21.4.4.25 Date.prototype.setMonth ( month [ , date ] )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. Let m be ? ToNumber(month).
  5. If date is present, let dt be ? ToNumber(date).
  6. If t is NaN, return NaN.
  7. Set t to LocalTime(t).
  8. If date is not present, let dt be DateFromTime(t).
  9. Let newDate be MakeDate(MakeDay(YearFromTime(t), m, dt), TimeWithinDay(t)).
  10. Let u be TimeClip(UTC(newDate)).
  11. Set dateObject.[[DateValue]] to u.
  12. Return u.

The "length" property of this method is 2𝔽.

Note

If date is not present, this method behaves as if date was present with the value getDate().

21.4.4.26 Date.prototype.setSeconds ( sec [ , ms ] )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. Let s be ? ToNumber(sec).
  5. If ms is present, let milli be ? ToNumber(ms).
  6. If t is NaN, return NaN.
  7. Set t to LocalTime(t).
  8. If ms is not present, let milli be msFromTime(t).
  9. Let date be MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), s, milli)).
  10. Let u be TimeClip(UTC(date)).
  11. Set dateObject.[[DateValue]] to u.
  12. Return u.

The "length" property of this method is 2𝔽.

Note

If ms is not present, this method behaves as if ms was present with the value getMilliseconds().

21.4.4.27 Date.prototype.setTime ( time )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be ? ToNumber(time).
  4. Let v be TimeClip(t).
  5. Set dateObject.[[DateValue]] to v.
  6. Return v.

21.4.4.28 Date.prototype.setUTCDate ( date )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. Let dt be ? ToNumber(date).
  5. If t is NaN, return NaN.
  6. Let newDate be MakeDate(MakeDay(YearFromTime(t), MonthFromTime(t), dt), TimeWithinDay(t)).
  7. Let v be TimeClip(newDate).
  8. Set dateObject.[[DateValue]] to v.
  9. Return v.

21.4.4.29 Date.prototype.setUTCFullYear ( year [ , month [ , date ] ] )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, set t to +0𝔽.
  5. Let y be ? ToNumber(year).
  6. If month is not present, let m be MonthFromTime(t); otherwise let m be ? ToNumber(month).
  7. If date is not present, let dt be DateFromTime(t); otherwise let dt be ? ToNumber(date).
  8. Let newDate be MakeDate(MakeDay(y, m, dt), TimeWithinDay(t)).
  9. Let v be TimeClip(newDate).
  10. Set dateObject.[[DateValue]] to v.
  11. Return v.

The "length" property of this method is 3𝔽.

Note

If month is not present, this method behaves as if month was present with the value getUTCMonth(). If date is not present, it behaves as if date was present with the value getUTCDate().

21.4.4.30 Date.prototype.setUTCHours ( hour [ , min [ , sec [ , ms ] ] ] )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. Let h be ? ToNumber(hour).
  5. If min is present, let m be ? ToNumber(min).
  6. If sec is present, let s be ? ToNumber(sec).
  7. If ms is present, let milli be ? ToNumber(ms).
  8. If t is NaN, return NaN.
  9. If min is not present, let m be MinFromTime(t).
  10. If sec is not present, let s be SecFromTime(t).
  11. If ms is not present, let milli be msFromTime(t).
  12. Let date be MakeDate(Day(t), MakeTime(h, m, s, milli)).
  13. Let v be TimeClip(date).
  14. Set dateObject.[[DateValue]] to v.
  15. Return v.

The "length" property of this method is 4𝔽.

Note

If min is not present, this method behaves as if min was present with the value getUTCMinutes(). If sec is not present, it behaves as if sec was present with the value getUTCSeconds(). If ms is not present, it behaves as if ms was present with the value getUTCMilliseconds().

21.4.4.31 Date.prototype.setUTCMilliseconds ( ms )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. Set ms to ? ToNumber(ms).
  5. If t is NaN, return NaN.
  6. Let time be MakeTime(HourFromTime(t), MinFromTime(t), SecFromTime(t), ms).
  7. Let v be TimeClip(MakeDate(Day(t), time)).
  8. Set dateObject.[[DateValue]] to v.
  9. Return v.

21.4.4.32 Date.prototype.setUTCMinutes ( min [ , sec [ , ms ] ] )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. Let m be ? ToNumber(min).
  5. If sec is present, let s be ? ToNumber(sec).
  6. If ms is present, let milli be ? ToNumber(ms).
  7. If t is NaN, return NaN.
  8. If sec is not present, let s be SecFromTime(t).
  9. If ms is not present, let milli be msFromTime(t).
  10. Let date be MakeDate(Day(t), MakeTime(HourFromTime(t), m, s, milli)).
  11. Let v be TimeClip(date).
  12. Set dateObject.[[DateValue]] to v.
  13. Return v.

The "length" property of this method is 3𝔽.

Note

If sec is not present, this method behaves as if sec was present with the value getUTCSeconds(). If ms is not present, it behaves as if ms was present with the value return by getUTCMilliseconds().

21.4.4.33 Date.prototype.setUTCMonth ( month [ , date ] )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. Let m be ? ToNumber(month).
  5. If date is present, let dt be ? ToNumber(date).
  6. If t is NaN, return NaN.
  7. If date is not present, let dt be DateFromTime(t).
  8. Let newDate be MakeDate(MakeDay(YearFromTime(t), m, dt), TimeWithinDay(t)).
  9. Let v be TimeClip(newDate).
  10. Set dateObject.[[DateValue]] to v.
  11. Return v.

The "length" property of this method is 2𝔽.

Note

If date is not present, this method behaves as if date was present with the value getUTCDate().

21.4.4.34 Date.prototype.setUTCSeconds ( sec [ , ms ] )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. Let s be ? ToNumber(sec).
  5. If ms is present, let milli be ? ToNumber(ms).
  6. If t is NaN, return NaN.
  7. If ms is not present, let milli be msFromTime(t).
  8. Let date be MakeDate(Day(t), MakeTime(HourFromTime(t), MinFromTime(t), s, milli)).
  9. Let v be TimeClip(date).
  10. Set dateObject.[[DateValue]] to v.
  11. Return v.

The "length" property of this method is 2𝔽.

Note

If ms is not present, this method behaves as if ms was present with the value getUTCMilliseconds().

21.4.4.35 Date.prototype.toDateString ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let tv be dateObject.[[DateValue]].
  4. If tv is NaN, return "Invalid Date".
  5. Let t be LocalTime(tv).
  6. Return DateString(t).

21.4.4.36 Date.prototype.toISOString ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let tv be dateObject.[[DateValue]].
  4. If tv is NaN, throw a RangeError exception.
  5. Assert: tv is an integral Number.
  6. If tv corresponds with a year that cannot be represented in the Date Time String Format, throw a RangeError exception.
  7. Return a String representation of tv in the Date Time String Format on the UTC time scale, including all format elements and the UTC offset representation "Z".

21.4.4.37 Date.prototype.toJSON ( key )

This method provides a String representation of a Date for use by JSON.stringify (25.5.2).

It performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let tv be ? ToPrimitive(O, number).
  3. If tv is a Number and tv is not finite, return null.
  4. Return ? Invoke(O, "toISOString").
Note 1

The argument is ignored.

Note 2

This method is intentionally generic; it does not require that its this value be a Date. Therefore, it can be transferred to other kinds of objects for use as a method. However, it does require that any such object have a toISOString method.

21.4.4.38 Date.prototype.toLocaleDateString ( [ reserved1 [ , reserved2 ] ] )

An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement this method as specified in the ECMA-402 specification. If an ECMAScript implementation does not include the ECMA-402 API the following specification of this method is used:

This method returns a String value. The contents of the String are implementation-defined, but are intended to represent the “date” portion of the Date in the current time zone in a convenient, human-readable form that corresponds to the conventions of the host environment's current locale.

The meaning of the optional parameters to this method are defined in the ECMA-402 specification; implementations that do not include ECMA-402 support must not use those parameter positions for anything else.

21.4.4.39 Date.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] )

An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement this method as specified in the ECMA-402 specification. If an ECMAScript implementation does not include the ECMA-402 API the following specification of this method is used:

This method returns a String value. The contents of the String are implementation-defined, but are intended to represent the Date in the current time zone in a convenient, human-readable form that corresponds to the conventions of the host environment's current locale.

The meaning of the optional parameters to this method are defined in the ECMA-402 specification; implementations that do not include ECMA-402 support must not use those parameter positions for anything else.

21.4.4.40 Date.prototype.toLocaleTimeString ( [ reserved1 [ , reserved2 ] ] )

An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement this method as specified in the ECMA-402 specification. If an ECMAScript implementation does not include the ECMA-402 API the following specification of this method is used:

This method returns a String value. The contents of the String are implementation-defined, but are intended to represent the “time” portion of the Date in the current time zone in a convenient, human-readable form that corresponds to the conventions of the host environment's current locale.

The meaning of the optional parameters to this method are defined in the ECMA-402 specification; implementations that do not include ECMA-402 support must not use those parameter positions for anything else.

21.4.4.41 Date.prototype.toString ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let tv be dateObject.[[DateValue]].
  4. Return ToDateString(tv).
Note 1

For any Date d such that d.[[DateValue]] is evenly divisible by 1000, the result of Date.parse(d.toString()) = d.valueOf(). See 21.4.3.2.

Note 2

This method is not generic; it throws a TypeError exception if its this value is not a Date. Therefore, it cannot be transferred to other kinds of objects for use as a method.

21.4.4.41.1 TimeString ( tv )

The abstract operation TimeString takes argument tv (a Number, but not NaN) and returns a String. It performs the following steps when called:

  1. Let hour be ToZeroPaddedDecimalString((HourFromTime(tv)), 2).
  2. Let minute be ToZeroPaddedDecimalString((MinFromTime(tv)), 2).
  3. Let second be ToZeroPaddedDecimalString((SecFromTime(tv)), 2).
  4. Return the string-concatenation of hour, ":", minute, ":", second, the code unit 0x0020 (SPACE), and "GMT".

21.4.4.41.2 DateString ( tv )

The abstract operation DateString takes argument tv (a Number, but not NaN) and returns a String. It performs the following steps when called:

  1. Let weekday be the Name of the entry in Table 65 with the Number WeekDay(tv).
  2. Let month be the Name of the entry in Table 66 with the Number MonthFromTime(tv).
  3. Let day be ToZeroPaddedDecimalString((DateFromTime(tv)), 2).
  4. Let yv be YearFromTime(tv).
  5. If yv is +0𝔽 or yv > +0𝔽, let yearSign be the empty String; otherwise let yearSign be "-".
  6. Let paddedYear be ToZeroPaddedDecimalString(abs((yv)), 4).
  7. Return the string-concatenation of weekday, the code unit 0x0020 (SPACE), month, the code unit 0x0020 (SPACE), day, the code unit 0x0020 (SPACE), yearSign, and paddedYear.
Table 65: Names of days of the week
Number Name
+0𝔽 "Sun"
1𝔽 "Mon"
2𝔽 "Tue"
3𝔽 "Wed"
4𝔽 "Thu"
5𝔽 "Fri"
6𝔽 "Sat"
Table 66: Names of months of the year
Number Name
+0𝔽 "Jan"
1𝔽 "Feb"
2𝔽 "Mar"
3𝔽 "Apr"
4𝔽 "May"
5𝔽 "Jun"
6𝔽 "Jul"
7𝔽 "Aug"
8𝔽 "Sep"
9𝔽 "Oct"
10𝔽 "Nov"
11𝔽 "Dec"

21.4.4.41.3 TimeZoneString ( tv )

The abstract operation TimeZoneString takes argument tv (an integral Number) and returns a String. It performs the following steps when called:

  1. Let systemTimeZoneIdentifier be SystemTimeZoneIdentifier().
  2. If IsTimeZoneOffsetString(systemTimeZoneIdentifier) is true, then
    1. Let offsetNs be ParseTimeZoneOffsetString(systemTimeZoneIdentifier).
  3. Else,
    1. Let offsetNs be GetNamedTimeZoneOffsetNanoseconds(systemTimeZoneIdentifier, ((tv) × 106)).
  4. Let offset be 𝔽(truncate(offsetNs / 106)).
  5. If offset is +0𝔽 or offset > +0𝔽, then
    1. Let offsetSign be "+".
    2. Let absOffset be offset.
  6. Else,
    1. Let offsetSign be "-".
    2. Let absOffset be -offset.
  7. Let offsetMin be ToZeroPaddedDecimalString((MinFromTime(absOffset)), 2).
  8. Let offsetHour be ToZeroPaddedDecimalString((HourFromTime(absOffset)), 2).
  9. Let tzName be an implementation-defined string that is either the empty String or the string-concatenation of the code unit 0x0020 (SPACE), the code unit 0x0028 (LEFT PARENTHESIS), an implementation-defined timezone name, and the code unit 0x0029 (RIGHT PARENTHESIS).
  10. Return the string-concatenation of offsetSign, offsetHour, offsetMin, and tzName.

21.4.4.41.4 ToDateString ( tv )

The abstract operation ToDateString takes argument tv (an integral Number or NaN) and returns a String. It performs the following steps when called:

  1. If tv is NaN, return "Invalid Date".
  2. Let t be LocalTime(tv).
  3. Return the string-concatenation of DateString(t), the code unit 0x0020 (SPACE), TimeString(t), and TimeZoneString(tv).

21.4.4.42 Date.prototype.toTimeString ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let tv be dateObject.[[DateValue]].
  4. If tv is NaN, return "Invalid Date".
  5. Let t be LocalTime(tv).
  6. Return the string-concatenation of TimeString(t) and TimeZoneString(tv).

21.4.4.43 Date.prototype.toUTCString ( )

This method returns a String value representing the instant in time corresponding to the this value. The format of the String is based upon "HTTP-date" from RFC 7231, generalized to support the full range of times supported by ECMAScript Dates.

It performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let tv be dateObject.[[DateValue]].
  4. If tv is NaN, return "Invalid Date".
  5. Let weekday be the Name of the entry in Table 65 with the Number WeekDay(tv).
  6. Let month be the Name of the entry in Table 66 with the Number MonthFromTime(tv).
  7. Let day be ToZeroPaddedDecimalString((DateFromTime(tv)), 2).
  8. Let yv be YearFromTime(tv).
  9. If yv is +0𝔽 or yv > +0𝔽, let yearSign be the empty String; otherwise let yearSign be "-".
  10. Let paddedYear be ToZeroPaddedDecimalString(abs((yv)), 4).
  11. Return the string-concatenation of weekday, ",", the code unit 0x0020 (SPACE), day, the code unit 0x0020 (SPACE), month, the code unit 0x0020 (SPACE), yearSign, paddedYear, the code unit 0x0020 (SPACE), and TimeString(tv).

21.4.4.44 Date.prototype.valueOf ( )

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Return dateObject.[[DateValue]].

21.4.4.45 Date.prototype [ %Symbol.toPrimitive% ] ( hint )

This method is called by ECMAScript language operators to convert a Date to a primitive value. The allowed values for hint are "default", "number", and "string". Dates are unique among built-in ECMAScript object in that they treat "default" as being equivalent to "string", All other built-in ECMAScript objects treat "default" as being equivalent to "number".

It performs the following steps when called:

  1. Let O be the this value.
  2. If O is not an Object, throw a TypeError exception.
  3. If hint is either "string" or "default", then
    1. Let tryFirst be string.
  4. Else if hint is "number", then
    1. Let tryFirst be number.
  5. Else,
    1. Throw a TypeError exception.
  6. Return ? OrdinaryToPrimitive(O, tryFirst).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

The value of the "name" property of this method is "[Symbol.toPrimitive]".

21.4.5 Properties of Date Instances

Date instances are ordinary objects that inherit properties from the Date prototype object. Date instances also have a [[DateValue]] internal slot. The [[DateValue]] internal slot is the time value represented by this Date.

22 Text Processing

22.1 String Objects

22.1.1 The String Constructor

The String constructor:

  • is %String%.
  • is the initial value of the "String" property of the global object.
  • creates and initializes a new String object when called as a constructor.
  • performs a type conversion when called as a function rather than as a constructor.
  • may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified String behaviour must include a super call to the String constructor to create and initialize the subclass instance with a [[StringData]] internal slot.

22.1.1.1 String ( value )

This function performs the following steps when called:

  1. If value is not present, then
    1. Let s be the empty String.
  2. Else,
    1. If NewTarget is undefined and value is a Symbol, return SymbolDescriptiveString(value).
    2. Let s be ? ToString(value).
  3. If NewTarget is undefined, return s.
  4. Return StringCreate(s, ? GetPrototypeFromConstructor(NewTarget, "%String.prototype%")).

22.1.2 Properties of the String Constructor

The String constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

22.1.2.1 String.fromCharCode ( ...codeUnits )

This function may be called with any number of arguments which form the rest parameter codeUnits.

It performs the following steps when called:

  1. Let result be the empty String.
  2. For each element next of codeUnits, do
    1. Let nextCU be the code unit whose numeric value is (? ToUint16(next)).
    2. Set result to the string-concatenation of result and nextCU.
  3. Return result.

The "length" property of this function is 1𝔽.

22.1.2.2 String.fromCodePoint ( ...codePoints )

This function may be called with any number of arguments which form the rest parameter codePoints.

It performs the following steps when called:

  1. Let result be the empty String.
  2. For each element next of codePoints, do
    1. Let nextCP be ? ToNumber(next).
    2. If nextCP is not an integral Number, throw a RangeError exception.
    3. If (nextCP) < 0 or (nextCP) > 0x10FFFF, throw a RangeError exception.
    4. Set result to the string-concatenation of result and UTF16EncodeCodePoint((nextCP)).
  3. Assert: If codePoints is empty, then result is the empty String.
  4. Return result.

The "length" property of this function is 1𝔽.

22.1.2.3 String.prototype

The initial value of String.prototype is the String prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

22.1.2.4 String.raw ( template, ...substitutions )

This function may be called with a variable number of arguments. The first argument is template and the remainder of the arguments form the List substitutions.

It performs the following steps when called:

  1. Let substitutionCount be the number of elements in substitutions.
  2. Let cooked be ? ToObject(template).
  3. Let literals be ? ToObject(? Get(cooked, "raw")).
  4. Let literalCount be ? LengthOfArrayLike(literals).
  5. If literalCount ≤ 0, return the empty String.
  6. Let R be the empty String.
  7. Let nextIndex be 0.
  8. Repeat,
    1. Let nextLiteralVal be ? Get(literals, ! ToString(𝔽(nextIndex))).
    2. Let nextLiteral be ? ToString(nextLiteralVal).
    3. Set R to the string-concatenation of R and nextLiteral.
    4. If nextIndex + 1 = literalCount, return R.
    5. If nextIndex < substitutionCount, then
      1. Let nextSubVal be substitutions[nextIndex].
      2. Let nextSub be ? ToString(nextSubVal).
      3. Set R to the string-concatenation of R and nextSub.
    6. Set nextIndex to nextIndex + 1.
Note

This function is intended for use as a tag function of a Tagged Template (13.3.11). When called as such, the first argument will be a well formed template object and the rest parameter will contain the substitution values.

22.1.3 Properties of the String Prototype Object

The String prototype object:

  • is %String.prototype%.
  • is a String exotic object and has the internal methods specified for such objects.
  • has a [[StringData]] internal slot whose value is the empty String.
  • has a "length" property whose initial value is +0𝔽 and whose attributes are { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.

Unless explicitly stated otherwise, the methods of the String prototype object defined below are not generic and the this value passed to them must be either a String value or an object that has a [[StringData]] internal slot that has been initialized to a String value.

22.1.3.1 String.prototype.at ( index )

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let len be the length of S.
  4. Let relativeIndex be ? ToIntegerOrInfinity(index).
  5. If relativeIndex ≥ 0, then
    1. Let k be relativeIndex.
  6. Else,
    1. Let k be len + relativeIndex.
  7. If k < 0 or klen, return undefined.
  8. Return the substring of S from k to k + 1.

22.1.3.2 String.prototype.charAt ( pos )

Note 1

This method returns a single element String containing the code unit at index pos within the String value resulting from converting this object to a String. If there is no element at that index, the result is the empty String. The result is a String value, not a String object.

If pos is an integral Number, then the result of x.charAt(pos) is equivalent to the result of x.substring(pos, pos + 1).

This method performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let position be ? ToIntegerOrInfinity(pos).
  4. Let size be the length of S.
  5. If position < 0 or positionsize, return the empty String.
  6. Return the substring of S from position to position + 1.
Note 2

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.3 String.prototype.charCodeAt ( pos )

Note 1

This method returns a Number (a non-negative integral Number less than 216) that is the numeric value of the code unit at index pos within the String resulting from converting this object to a String. If there is no element at that index, the result is NaN.

This method performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let position be ? ToIntegerOrInfinity(pos).
  4. Let size be the length of S.
  5. If position < 0 or positionsize, return NaN.
  6. Return the Number value for the numeric value of the code unit at index position within the String S.
Note 2

This method is intentionally generic; it does not require that its this value be a String object. Therefore it can be transferred to other kinds of objects for use as a method.

22.1.3.4 String.prototype.codePointAt ( pos )

Note 1

This method returns a non-negative integral Number less than or equal to 0x10FFFF𝔽 that is the numeric value of the UTF-16 encoded code point (6.1.4) starting at the string element at index pos within the String resulting from converting this object to a String. If there is no element at that index, the result is undefined. If a valid UTF-16 surrogate pair does not begin at pos, the result is the code unit at pos.

This method performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let position be ? ToIntegerOrInfinity(pos).
  4. Let size be the length of S.
  5. If position < 0 or positionsize, return undefined.
  6. Let cp be CodePointAt(S, position).
  7. Return 𝔽(cp.[[CodePoint]]).
Note 2

This method is intentionally generic; it does not require that its this value be a String object. Therefore it can be transferred to other kinds of objects for use as a method.

22.1.3.5 String.prototype.concat ( ...args )

Note 1

When this method is called it returns the String value consisting of the code units of the this value (converted to a String) followed by the code units of each of the arguments converted to a String. The result is a String value, not a String object.

This method performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let R be S.
  4. For each element next of args, do
    1. Let nextString be ? ToString(next).
    2. Set R to the string-concatenation of R and nextString.
  5. Return R.

The "length" property of this method is 1𝔽.

Note 2

This method is intentionally generic; it does not require that its this value be a String object. Therefore it can be transferred to other kinds of objects for use as a method.

22.1.3.6 String.prototype.constructor

The initial value of String.prototype.constructor is %String%.

22.1.3.7 String.prototype.endsWith ( searchString [ , endPosition ] )

This method performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let isRegExp be ? IsRegExp(searchString).
  4. If isRegExp is true, throw a TypeError exception.
  5. Let searchStr be ? ToString(searchString).
  6. Let len be the length of S.
  7. If endPosition is undefined, let pos be len; else let pos be ? ToIntegerOrInfinity(endPosition).
  8. Let end be the result of clamping pos between 0 and len.
  9. Let searchLength be the length of searchStr.
  10. If searchLength = 0, return true.
  11. Let start be end - searchLength.
  12. If start < 0, return false.
  13. Let substring be the substring of S from start to end.
  14. If substring is searchStr, return true.
  15. Return false.
Note 1

This method returns true if the sequence of code units of searchString converted to a String is the same as the corresponding code units of this object (converted to a String) starting at endPosition - length(this). Otherwise it returns false.

Note 2

Throwing an exception if the first argument is a RegExp is specified in order to allow future editions to define extensions that allow such argument values.

Note 3

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.8 String.prototype.includes ( searchString [ , position ] )

This method performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let isRegExp be ? IsRegExp(searchString).
  4. If isRegExp is true, throw a TypeError exception.
  5. Let searchStr be ? ToString(searchString).
  6. Let pos be ? ToIntegerOrInfinity(position).
  7. Assert: If position is undefined, then pos is 0.
  8. Let len be the length of S.
  9. Let start be the result of clamping pos between 0 and len.
  10. Let index be StringIndexOf(S, searchStr, start).
  11. If index is not-found, return false.
  12. Return true.
Note 1

If searchString appears as a substring of the result of converting this object to a String, at one or more indices that are greater than or equal to position, this function returns true; otherwise, it returns false. If position is undefined, 0 is assumed, so as to search all of the String.

Note 2

Throwing an exception if the first argument is a RegExp is specified in order to allow future editions to define extensions that allow such argument values.

Note 3

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.9 String.prototype.indexOf ( searchString [ , position ] )

Note 1

If searchString appears as a substring of the result of converting this object to a String, at one or more indices that are greater than or equal to position, then the smallest such index is returned; otherwise, -1𝔽 is returned. If position is undefined, +0𝔽 is assumed, so as to search all of the String.

This method performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let searchStr be ? ToString(searchString).
  4. Let pos be ? ToIntegerOrInfinity(position).
  5. Assert: If position is undefined, then pos is 0.
  6. Let len be the length of S.
  7. Let start be the result of clamping pos between 0 and len.
  8. Let result be StringIndexOf(S, searchStr, start).
  9. If result is not-found, return -1𝔽.
  10. Return 𝔽(result).
Note 2

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.10 String.prototype.isWellFormed ( )

This method performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Return IsStringWellFormedUnicode(S).

22.1.3.11 String.prototype.lastIndexOf ( searchString [ , position ] )

Note 1

If searchString appears as a substring of the result of converting this object to a String at one or more indices that are smaller than or equal to position, then the greatest such index is returned; otherwise, -1𝔽 is returned. If position is undefined, the length of the String value is assumed, so as to search all of the String.

This method performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let searchStr be ? ToString(searchString).
  4. Let numPos be ? ToNumber(position).
  5. Assert: If position is undefined, then numPos is NaN.
  6. If numPos is NaN, let pos be +∞; otherwise let pos be ! ToIntegerOrInfinity(numPos).
  7. Let len be the length of S.
  8. Let searchLen be the length of searchStr.
  9. Let start be the result of clamping pos between 0 and len - searchLen.
  10. Let result be StringLastIndexOf(S, searchStr, start).
  11. If result is not-found, return -1𝔽.
  12. Return 𝔽(result).
Note 2

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.12 String.prototype.localeCompare ( that [ , reserved1 [ , reserved2 ] ] )

An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement this method as specified in the ECMA-402 specification. If an ECMAScript implementation does not include the ECMA-402 API the following specification of this method is used:

This method returns a Number other than NaN representing the result of an implementation-defined locale-sensitive String comparison of the this value (converted to a String S) with that (converted to a String thatValue). The result is intended to correspond with a sort order of String values according to conventions of the host environment's current locale, and will be negative when S is ordered before thatValue, positive when S is ordered after thatValue, and zero in all other cases (representing no relative ordering between S and thatValue).

Before performing the comparisons, this method performs the following steps to prepare the Strings:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let thatValue be ? ToString(that).

The meaning of the optional second and third parameters to this method are defined in the ECMA-402 specification; implementations that do not include ECMA-402 support must not assign any other interpretation to those parameter positions.

The actual return values are implementation-defined to permit encoding additional information in them, but this method, when considered as a method of two arguments, is required to be a consistent comparator defining a total ordering on the set of all Strings. This method is also required to recognize and honour canonical equivalence according to the Unicode Standard, including returning +0𝔽 when comparing distinguishable Strings that are canonically equivalent.

Note 1

This method itself is not directly suitable as an argument to Array.prototype.sort because the latter requires a function of two arguments.

Note 2

This method may rely on whatever language- and/or locale-sensitive comparison functionality is available to the ECMAScript environment from the host environment, and is intended to compare according to the conventions of the host environment's current locale. However, regardless of comparison capabilities, this method must recognize and honour canonical equivalence according to the Unicode Standard—for example, the following comparisons must all return +0𝔽:

// Å ANGSTROM SIGN vs.
// Å LATIN CAPITAL LETTER A + COMBINING RING ABOVE
"\u212B".localeCompare("A\u030A")

// Ω OHM SIGN vs.
// Ω GREEK CAPITAL LETTER OMEGA
"\u2126".localeCompare("\u03A9")

// ṩ LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE vs.
// ṩ LATIN SMALL LETTER S + COMBINING DOT ABOVE + COMBINING DOT BELOW
"\u1E69".localeCompare("s\u0307\u0323")

// ḍ̇ LATIN SMALL LETTER D WITH DOT ABOVE + COMBINING DOT BELOW vs.
// ḍ̇ LATIN SMALL LETTER D WITH DOT BELOW + COMBINING DOT ABOVE
"\u1E0B\u0323".localeCompare("\u1E0D\u0307")

// 가 HANGUL CHOSEONG KIYEOK + HANGUL JUNGSEONG A vs.
// 가 HANGUL SYLLABLE GA
"\u1100\u1161".localeCompare("\uAC00")

For a definition and discussion of canonical equivalence see the Unicode Standard, chapters 2 and 3, as well as Unicode Standard Annex #15, Unicode Normalization Forms and Unicode Technical Note #5, Canonical Equivalence in Applications. Also see Unicode Technical Standard #10, Unicode Collation Algorithm.

It is recommended that this method should not honour Unicode compatibility equivalents or compatibility decompositions as defined in the Unicode Standard, chapter 3, section 3.7.

Note 3

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.13 String.prototype.match ( regexp )

This method performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. If regexp is neither undefined nor null, then
    1. Let matcher be ? GetMethod(regexp, %Symbol.match%).
    2. If matcher is not undefined, then
      1. Return ? Call(matcher, regexp, « O »).
  3. Let S be ? ToString(O).
  4. Let rx be ? RegExpCreate(regexp, undefined).
  5. Return ? Invoke(rx, %Symbol.match%, « S »).
Note

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.14 String.prototype.matchAll ( regexp )

This method performs a regular expression match of the String representing the this value against regexp and returns an iterator that yields match results. Each match result is an Array containing the matched portion of the String as the first element, followed by the portions matched by any capturing groups. If the regular expression never matches, the returned iterator does not yield any match results.

It performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. If regexp is neither undefined nor null, then
    1. Let isRegExp be ? IsRegExp(regexp).
    2. If isRegExp is true, then
      1. Let flags be ? Get(regexp, "flags").
      2. Perform ? RequireObjectCoercible(flags).
      3. If ? ToString(flags) does not contain "g", throw a TypeError exception.
    3. Let matcher be ? GetMethod(regexp, %Symbol.matchAll%).
    4. If matcher is not undefined, then
      1. Return ? Call(matcher, regexp, « O »).
  3. Let S be ? ToString(O).
  4. Let rx be ? RegExpCreate(regexp, "g").
  5. Return ? Invoke(rx, %Symbol.matchAll%, « S »).
Note 1
This method is intentionally generic, it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.
Note 2
Similarly to String.prototype.split, String.prototype.matchAll is designed to typically act without mutating its inputs.

22.1.3.15 String.prototype.normalize ( [ form ] )

This method performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. If form is undefined, let f be "NFC".
  4. Else, let f be ? ToString(form).
  5. If f is not one of "NFC", "NFD", "NFKC", or "NFKD", throw a RangeError exception.
  6. Let ns be the String value that is the result of normalizing S into the normalization form named by f as specified in the latest Unicode Standard, Normalization Forms.
  7. Return ns.
Note

This method is intentionally generic; it does not require that its this value be a String object. Therefore it can be transferred to other kinds of objects for use as a method.

22.1.3.16 String.prototype.padEnd ( maxLength [ , fillString ] )

This method performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Return ? StringPaddingBuiltinsImpl(O, maxLength, fillString, end).

22.1.3.17 String.prototype.padStart ( maxLength [ , fillString ] )

This method performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Return ? StringPaddingBuiltinsImpl(O, maxLength, fillString, start).

22.1.3.17.1 StringPaddingBuiltinsImpl ( O, maxLength, fillString, placement )

The abstract operation StringPaddingBuiltinsImpl takes arguments O (an ECMAScript language value), maxLength (an ECMAScript language value), fillString (an ECMAScript language value), and placement (start or end) and returns either a normal completion containing a String or a throw completion. It performs the following steps when called:

  1. Let S be ? ToString(O).
  2. Let intMaxLength be (? ToLength(maxLength)).
  3. Let stringLength be the length of S.
  4. If intMaxLengthstringLength, return S.
  5. If fillString is undefined, set fillString to the String value consisting solely of the code unit 0x0020 (SPACE).
  6. Else, set fillString to ? ToString(fillString).
  7. Return StringPad(S, intMaxLength, fillString, placement).

22.1.3.17.2 StringPad ( S, maxLength, fillString, placement )

The abstract operation StringPad takes arguments S (a String), maxLength (a non-negative integer), fillString (a String), and placement (start or end) and returns a String. It performs the following steps when called:

  1. Let stringLength be the length of S.
  2. If maxLengthstringLength, return S.
  3. If fillString is the empty String, return S.
  4. Let fillLen be maxLength - stringLength.
  5. Let truncatedStringFiller be the String value consisting of repeated concatenations of fillString truncated to length fillLen.
  6. If placement is start, return the string-concatenation of truncatedStringFiller and S.
  7. Else, return the string-concatenation of S and truncatedStringFiller.
Note 1

The argument maxLength will be clamped such that it can be no smaller than the length of S.

Note 2

The argument fillString defaults to " " (the String value consisting of the code unit 0x0020 SPACE).

22.1.3.17.3 ToZeroPaddedDecimalString ( n, minLength )

The abstract operation ToZeroPaddedDecimalString takes arguments n (a non-negative integer) and minLength (a non-negative integer) and returns a String. It performs the following steps when called:

  1. Let S be the String representation of n, formatted as a decimal number.
  2. Return StringPad(S, minLength, "0", start).

22.1.3.18 String.prototype.repeat ( count )

This method performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let n be ? ToIntegerOrInfinity(count).
  4. If n < 0 or n = +∞, throw a RangeError exception.
  5. If n = 0, return the empty String.
  6. Return the String value that is made from n copies of S appended together.
Note 1

This method creates the String value consisting of the code units of the this value (converted to String) repeated count times.

Note 2

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.19 String.prototype.replace ( searchValue, replaceValue )

This method performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. If searchValue is neither undefined nor null, then
    1. Let replacer be ? GetMethod(searchValue, %Symbol.replace%).
    2. If replacer is not undefined, then
      1. Return ? Call(replacer, searchValue, « O, replaceValue »).
  3. Let string be ? ToString(O).
  4. Let searchString be ? ToString(searchValue).
  5. Let functionalReplace be IsCallable(replaceValue).
  6. If functionalReplace is false, then
    1. Set replaceValue to ? ToString(replaceValue).
  7. Let searchLength be the length of searchString.
  8. Let position be StringIndexOf(string, searchString, 0).
  9. If position is not-found, return string.
  10. Let preceding be the substring of string from 0 to position.
  11. Let following be the substring of string from position + searchLength.
  12. If functionalReplace is true, then
    1. Let replacement be ? ToString(? Call(replaceValue, undefined, « searchString, 𝔽(position), string »)).
  13. Else,
    1. Assert: replaceValue is a String.
    2. Let captures be a new empty List.
    3. Let replacement be ! GetSubstitution(searchString, string, position, captures, undefined, replaceValue).
  14. Return the string-concatenation of preceding, replacement, and following.
Note

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.19.1 GetSubstitution ( matched, str, position, captures, namedCaptures, replacementTemplate )

The abstract operation GetSubstitution takes arguments matched (a String), str (a String), position (a non-negative integer), captures (a List of either Strings or undefined), namedCaptures (an Object or undefined), and replacementTemplate (a String) and returns either a normal completion containing a String or a throw completion. For the purposes of this abstract operation, a decimal digit is a code unit in the inclusive interval from 0x0030 (DIGIT ZERO) to 0x0039 (DIGIT NINE). It performs the following steps when called:

  1. Let stringLength be the length of str.
  2. Assert: positionstringLength.
  3. Let result be the empty String.
  4. Let templateRemainder be replacementTemplate.
  5. Repeat, while templateRemainder is not the empty String,
    1. NOTE: The following steps isolate ref (a prefix of templateRemainder), determine refReplacement (its replacement), and then append that replacement to result.
    2. If templateRemainder starts with "$$", then
      1. Let ref be "$$".
      2. Let refReplacement be "$".
    3. Else if templateRemainder starts with "$`", then
      1. Let ref be "$`".
      2. Let refReplacement be the substring of str from 0 to position.
    4. Else if templateRemainder starts with "$&", then
      1. Let ref be "$&".
      2. Let refReplacement be matched.
    5. Else if templateRemainder starts with "$'" (0x0024 (DOLLAR SIGN) followed by 0x0027 (APOSTROPHE)), then
      1. Let ref be "$'".
      2. Let matchLength be the length of matched.
      3. Let tailPos be position + matchLength.
      4. Let refReplacement be the substring of str from min(tailPos, stringLength).
      5. NOTE: tailPos can exceed stringLength only if this abstract operation was invoked by a call to the intrinsic %Symbol.replace% method of %RegExp.prototype% on an object whose "exec" property is not the intrinsic %RegExp.prototype.exec%.
    6. Else if templateRemainder starts with "$" followed by 1 or more decimal digits, then
      1. If templateRemainder starts with "$" followed by 2 or more decimal digits, let digitCount be 2; otherwise let digitCount be 1.
      2. Let digits be the substring of templateRemainder from 1 to 1 + digitCount.
      3. Let index be (StringToNumber(digits)).
      4. Assert: 0 ≤ index ≤ 99.
      5. Let captureLen be the number of elements in captures.
      6. If index > captureLen and digitCount = 2, then
        1. NOTE: When a two-digit replacement pattern specifies an index exceeding the count of capturing groups, it is treated as a one-digit replacement pattern followed by a literal digit.
        2. Set digitCount to 1.
        3. Set digits to the substring of digits from 0 to 1.
        4. Set index to (StringToNumber(digits)).
      7. Let ref be the substring of templateRemainder from 0 to 1 + digitCount.
      8. If 1 ≤ indexcaptureLen, then
        1. Let capture be captures[index - 1].
        2. If capture is undefined, then
          1. Let refReplacement be the empty String.
        3. Else,
          1. Let refReplacement be capture.
      9. Else,
        1. Let refReplacement be ref.
    7. Else if templateRemainder starts with "$<", then
      1. Let gtPos be StringIndexOf(templateRemainder, ">", 0).
      2. If gtPos is not-found or namedCaptures is undefined, then
        1. Let ref be "$<".
        2. Let refReplacement be ref.
      3. Else,
        1. Let ref be the substring of templateRemainder from 0 to gtPos + 1.
        2. Let groupName be the substring of templateRemainder from 2 to gtPos.
        3. Assert: namedCaptures is an Object.
        4. Let capture be ? Get(namedCaptures, groupName).
        5. If capture is undefined, then
          1. Let refReplacement be the empty String.
        6. Else,
          1. Let refReplacement be ? ToString(capture).
    8. Else,
      1. Let ref be the substring of templateRemainder from 0 to 1.
      2. Let refReplacement be ref.
    9. Let refLength be the length of ref.
    10. Set templateRemainder to the substring of templateRemainder from refLength.
    11. Set result to the string-concatenation of result and refReplacement.
  6. Return result.

22.1.3.20 String.prototype.replaceAll ( searchValue, replaceValue )

This method performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. If searchValue is neither undefined nor null, then
    1. Let isRegExp be ? IsRegExp(searchValue).
    2. If isRegExp is true, then
      1. Let flags be ? Get(searchValue, "flags").
      2. Perform ? RequireObjectCoercible(flags).
      3. If ? ToString(flags) does not contain "g", throw a TypeError exception.
    3. Let replacer be ? GetMethod(searchValue, %Symbol.replace%).
    4. If replacer is not undefined, then
      1. Return ? Call(replacer, searchValue, « O, replaceValue »).
  3. Let string be ? ToString(O).
  4. Let searchString be ? ToString(searchValue).
  5. Let functionalReplace be IsCallable(replaceValue).
  6. If functionalReplace is false, then
    1. Set replaceValue to ? ToString(replaceValue).
  7. Let searchLength be the length of searchString.
  8. Let advanceBy be max(1, searchLength).
  9. Let matchPositions be a new empty List.
  10. Let position be StringIndexOf(string, searchString, 0).
  11. Repeat, while position is not not-found,
    1. Append position to matchPositions.
    2. Set position to StringIndexOf(string, searchString, position + advanceBy).
  12. Let endOfLastMatch be 0.
  13. Let result be the empty String.
  14. For each element p of matchPositions, do
    1. Let preserved be the substring of string from endOfLastMatch to p.
    2. If functionalReplace is true, then
      1. Let replacement be ? ToString(? Call(replaceValue, undefined, « searchString, 𝔽(p), string »)).
    3. Else,
      1. Assert: replaceValue is a String.
      2. Let captures be a new empty List.
      3. Let replacement be ! GetSubstitution(searchString, string, p, captures, undefined, replaceValue).
    4. Set result to the string-concatenation of result, preserved, and replacement.
    5. Set endOfLastMatch to p + searchLength.
  15. If endOfLastMatch < the length of string, then
    1. Set result to the string-concatenation of result and the substring of string from endOfLastMatch.
  16. Return result.

22.1.3.21 String.prototype.search ( regexp )

This method performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. If regexp is neither undefined nor null, then
    1. Let searcher be ? GetMethod(regexp, %Symbol.search%).
    2. If searcher is not undefined, then
      1. Return ? Call(searcher, regexp, « O »).
  3. Let string be ? ToString(O).
  4. Let rx be ? RegExpCreate(regexp, undefined).
  5. Return ? Invoke(rx, %Symbol.search%, « string »).
Note

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.22 String.prototype.slice ( start, end )

This method returns a substring of the result of converting this object to a String, starting from index start and running to, but not including, index end (or through the end of the String if end is undefined). If start is negative, it is treated as sourceLength + start where sourceLength is the length of the String. If end is negative, it is treated as sourceLength + end where sourceLength is the length of the String. The result is a String value, not a String object.

It performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let len be the length of S.
  4. Let intStart be ? ToIntegerOrInfinity(start).
  5. If intStart = -∞, let from be 0.
  6. Else if intStart < 0, let from be max(len + intStart, 0).
  7. Else, let from be min(intStart, len).
  8. If end is undefined, let intEnd be len; else let intEnd be ? ToIntegerOrInfinity(end).
  9. If intEnd = -∞, let to be 0.
  10. Else if intEnd < 0, let to be max(len + intEnd, 0).
  11. Else, let to be min(intEnd, len).
  12. If fromto, return the empty String.
  13. Return the substring of S from from to to.
Note

This method is intentionally generic; it does not require that its this value be a String object. Therefore it can be transferred to other kinds of objects for use as a method.

22.1.3.23 String.prototype.split ( separator, limit )

This method returns an Array into which substrings of the result of converting this object to a String have been stored. The substrings are determined by searching from left to right for occurrences of separator; these occurrences are not part of any String in the returned array, but serve to divide up the String value. The value of separator may be a String of any length or it may be an object, such as a RegExp, that has a %Symbol.split% method.

It performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. If separator is neither undefined nor null, then
    1. Let splitter be ? GetMethod(separator, %Symbol.split%).
    2. If splitter is not undefined, then
      1. Return ? Call(splitter, separator, « O, limit »).
  3. Let S be ? ToString(O).
  4. If limit is undefined, let lim be 232 - 1; else let lim be (? ToUint32(limit)).
  5. Let R be ? ToString(separator).
  6. If lim = 0, then
    1. Return CreateArrayFromList(« »).
  7. If separator is undefined, then
    1. Return CreateArrayFromListS »).
  8. Let separatorLength be the length of R.
  9. If separatorLength = 0, then
    1. Let strLen be the length of S.
    2. Let outLen be the result of clamping lim between 0 and strLen.
    3. Let head be the substring of S from 0 to outLen.
    4. Let codeUnits be a List consisting of the sequence of code units that are the elements of head.
    5. Return CreateArrayFromList(codeUnits).
  10. If S is the empty String, return CreateArrayFromListS »).
  11. Let substrings be a new empty List.
  12. Let i be 0.
  13. Let j be StringIndexOf(S, R, 0).
  14. Repeat, while j is not not-found,
    1. Let T be the substring of S from i to j.
    2. Append T to substrings.
    3. If the number of elements in substrings is lim, return CreateArrayFromList(substrings).
    4. Set i to j + separatorLength.
    5. Set j to StringIndexOf(S, R, i).
  15. Let T be the substring of S from i.
  16. Append T to substrings.
  17. Return CreateArrayFromList(substrings).
Note 1

The value of separator may be an empty String. In this case, separator does not match the empty substring at the beginning or end of the input String, nor does it match the empty substring at the end of the previous separator match. If separator is the empty String, the String is split up into individual code unit elements; the length of the result array equals the length of the String, and each substring contains one code unit.

If the this value is (or converts to) the empty String, the result depends on whether separator can match the empty String. If it can, the result array contains no elements. Otherwise, the result array contains one element, which is the empty String.

If separator is undefined, then the result array contains just one String, which is the this value (converted to a String). If limit is not undefined, then the output array is truncated so that it contains no more than limit elements.

Note 2

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.24 String.prototype.startsWith ( searchString [ , position ] )

This method performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let isRegExp be ? IsRegExp(searchString).
  4. If isRegExp is true, throw a TypeError exception.
  5. Let searchStr be ? ToString(searchString).
  6. Let len be the length of S.
  7. If position is undefined, let pos be 0; else let pos be ? ToIntegerOrInfinity(position).
  8. Let start be the result of clamping pos between 0 and len.
  9. Let searchLength be the length of searchStr.
  10. If searchLength = 0, return true.
  11. Let end be start + searchLength.
  12. If end > len, return false.
  13. Let substring be the substring of S from start to end.
  14. If substring is searchStr, return true.
  15. Return false.
Note 1

This method returns true if the sequence of code units of searchString converted to a String is the same as the corresponding code units of this object (converted to a String) starting at index position. Otherwise it returns false.

Note 2

Throwing an exception if the first argument is a RegExp is specified in order to allow future editions to define extensions that allow such argument values.

Note 3

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.25 String.prototype.substring ( start, end )

This method returns a substring of the result of converting this object to a String, starting from index start and running to, but not including, index end of the String (or through the end of the String if end is undefined). The result is a String value, not a String object.

If either argument is NaN or negative, it is replaced with zero; if either argument is strictly greater than the length of the String, it is replaced with the length of the String.

If start is strictly greater than end, they are swapped.

It performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let len be the length of S.
  4. Let intStart be ? ToIntegerOrInfinity(start).
  5. If end is undefined, let intEnd be len; else let intEnd be ? ToIntegerOrInfinity(end).
  6. Let finalStart be the result of clamping intStart between 0 and len.
  7. Let finalEnd be the result of clamping intEnd between 0 and len.
  8. Let from be min(finalStart, finalEnd).
  9. Let to be max(finalStart, finalEnd).
  10. Return the substring of S from from to to.
Note

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.26 String.prototype.toLocaleLowerCase ( [ reserved1 [ , reserved2 ] ] )

An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement this method as specified in the ECMA-402 specification. If an ECMAScript implementation does not include the ECMA-402 API the following specification of this method is used:

This method interprets a String value as a sequence of UTF-16 encoded code points, as described in 6.1.4.

It works exactly the same as toLowerCase except that it is intended to yield a locale-sensitive result corresponding with conventions of the host environment's current locale. There will only be a difference in the few cases (such as Turkish) where the rules for that language conflict with the regular Unicode case mappings.

The meaning of the optional parameters to this method are defined in the ECMA-402 specification; implementations that do not include ECMA-402 support must not use those parameter positions for anything else.

Note

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.27 String.prototype.toLocaleUpperCase ( [ reserved1 [ , reserved2 ] ] )

An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement this method as specified in the ECMA-402 specification. If an ECMAScript implementation does not include the ECMA-402 API the following specification of this method is used:

This method interprets a String value as a sequence of UTF-16 encoded code points, as described in 6.1.4.

It works exactly the same as toUpperCase except that it is intended to yield a locale-sensitive result corresponding with conventions of the host environment's current locale. There will only be a difference in the few cases (such as Turkish) where the rules for that language conflict with the regular Unicode case mappings.

The meaning of the optional parameters to this method are defined in the ECMA-402 specification; implementations that do not include ECMA-402 support must not use those parameter positions for anything else.

Note

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.28 String.prototype.toLowerCase ( )

This method interprets a String value as a sequence of UTF-16 encoded code points, as described in 6.1.4.

It performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let sText be StringToCodePoints(S).
  4. Let lowerText be toLowercase(sText), according to the Unicode Default Case Conversion algorithm.
  5. Let L be CodePointsToString(lowerText).
  6. Return L.

The result must be derived according to the locale-insensitive case mappings in the Unicode Character Database (this explicitly includes not only the file UnicodeData.txt, but also all locale-insensitive mappings in the file SpecialCasing.txt that accompanies it).

Note 1

The case mapping of some code points may produce multiple code points. In this case the result String may not be the same length as the source String. Because both toUpperCase and toLowerCase have context-sensitive behaviour, the methods are not symmetrical. In other words, s.toUpperCase().toLowerCase() is not necessarily equal to s.toLowerCase().

Note 2

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.29 String.prototype.toString ( )

This method performs the following steps when called:

  1. Return ? ThisStringValue(this value).
Note

For a String object, this method happens to return the same thing as the valueOf method.

22.1.3.30 String.prototype.toUpperCase ( )

This method interprets a String value as a sequence of UTF-16 encoded code points, as described in 6.1.4.

It behaves in exactly the same way as String.prototype.toLowerCase, except that the String is mapped using the toUppercase algorithm of the Unicode Default Case Conversion.

Note

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.31 String.prototype.toWellFormed ( )

This method returns a String representation of this object with all leading surrogates and trailing surrogates that are not part of a surrogate pair replaced with U+FFFD (REPLACEMENT CHARACTER).

It performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let strLen be the length of S.
  4. Let k be 0.
  5. Let result be the empty String.
  6. Repeat, while k < strLen,
    1. Let cp be CodePointAt(S, k).
    2. If cp.[[IsUnpairedSurrogate]] is true, then
      1. Set result to the string-concatenation of result and 0xFFFD (REPLACEMENT CHARACTER).
    3. Else,
      1. Set result to the string-concatenation of result and UTF16EncodeCodePoint(cp.[[CodePoint]]).
    4. Set k to k + cp.[[CodeUnitCount]].
  7. Return result.

22.1.3.32 String.prototype.trim ( )

This method interprets a String value as a sequence of UTF-16 encoded code points, as described in 6.1.4.

It performs the following steps when called:

  1. Let S be the this value.
  2. Return ? TrimString(S, start+end).
Note

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.32.1 TrimString ( string, where )

The abstract operation TrimString takes arguments string (an ECMAScript language value) and where (start, end, or start+end) and returns either a normal completion containing a String or a throw completion. It interprets string as a sequence of UTF-16 encoded code points, as described in 6.1.4. It performs the following steps when called:

  1. Let str be ? RequireObjectCoercible(string).
  2. Let S be ? ToString(str).
  3. If where is start, then
    1. Let T be the String value that is a copy of S with leading white space removed.
  4. Else if where is end, then
    1. Let T be the String value that is a copy of S with trailing white space removed.
  5. Else,
    1. Assert: where is start+end.
    2. Let T be the String value that is a copy of S with both leading and trailing white space removed.
  6. Return T.

The definition of white space is the union of WhiteSpace and LineTerminator. When determining whether a Unicode code point is in Unicode general category “Space_Separator” (“Zs”), code unit sequences are interpreted as UTF-16 encoded code point sequences as specified in 6.1.4.

22.1.3.33 String.prototype.trimEnd ( )

This method interprets a String value as a sequence of UTF-16 encoded code points, as described in 6.1.4.

It performs the following steps when called:

  1. Let S be the this value.
  2. Return ? TrimString(S, end).
Note

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.34 String.prototype.trimStart ( )

This method interprets a String value as a sequence of UTF-16 encoded code points, as described in 6.1.4.

It performs the following steps when called:

  1. Let S be the this value.
  2. Return ? TrimString(S, start).
Note

This method is intentionally generic; it does not require that its this value be a String object. Therefore, it can be transferred to other kinds of objects for use as a method.

22.1.3.35 String.prototype.valueOf ( )

This method performs the following steps when called:

  1. Return ? ThisStringValue(this value).

22.1.3.35.1 ThisStringValue ( value )

The abstract operation ThisStringValue takes argument value (an ECMAScript language value) and returns either a normal completion containing a String or a throw completion. It performs the following steps when called:

  1. If value is a String, return value.
  2. If value is an Object and value has a [[StringData]] internal slot, then
    1. Let s be value.[[StringData]].
    2. Assert: s is a String.
    3. Return s.
  3. Throw a TypeError exception.

22.1.3.36 String.prototype [ %Symbol.iterator% ] ( )

This method returns an iterator object that iterates over the code points of a String value, returning each code point as a String value.

It performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let s be ? ToString(O).
  3. Let closure be a new Abstract Closure with no parameters that captures s and performs the following steps when called:
    1. Let len be the length of s.
    2. Let position be 0.
    3. Repeat, while position < len,
      1. Let cp be CodePointAt(s, position).
      2. Let nextIndex be position + cp.[[CodeUnitCount]].
      3. Let resultString be the substring of s from position to nextIndex.
      4. Set position to nextIndex.
      5. Perform ? GeneratorYield(CreateIteratorResultObject(resultString, false)).
    4. Return NormalCompletion(unused).
  4. Return CreateIteratorFromClosure(closure, "%StringIteratorPrototype%", %StringIteratorPrototype%).

The value of the "name" property of this method is "[Symbol.iterator]".

22.1.4 Properties of String Instances

String instances are String exotic objects and have the internal methods specified for such objects. String instances inherit properties from the String prototype object. String instances also have a [[StringData]] internal slot. The [[StringData]] internal slot is the String value represented by this String object.

String instances have a "length" property, and a set of enumerable properties with integer-indexed names.

22.1.4.1 length

The number of elements in the String value represented by this String object.

Once a String object is initialized, this property is unchanging. It has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

22.1.5 String Iterator Objects

A String Iterator is an object that represents a specific iteration over some specific String instance object. There is not a named constructor for String Iterator objects. Instead, String Iterator objects are created by calling certain methods of String instance objects.

22.1.5.1 The %StringIteratorPrototype% Object

The %StringIteratorPrototype% object:

22.1.5.1.1 %StringIteratorPrototype%.next ( )

  1. Return ? GeneratorResume(this value, empty, "%StringIteratorPrototype%").

22.1.5.1.2 %StringIteratorPrototype% [ %Symbol.toStringTag% ]

The initial value of the %Symbol.toStringTag% property is the String value "String Iterator".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

22.2 RegExp (Regular Expression) Objects

A RegExp object contains a regular expression and the associated flags.

Note

The form and functionality of regular expressions is modelled after the regular expression facility in the Perl 5 programming language.

22.2.1 Patterns

The RegExp constructor applies the following grammar to the input pattern String. An error occurs if the grammar cannot interpret the String as an expansion of Pattern.

Syntax

Pattern[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Disjunction[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: Alternative[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Alternative[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] | Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Alternative[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: [empty] Alternative[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Term[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Term[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: Assertion[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Atom[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Atom[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Quantifier Assertion[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: ^ $ \b \B (?= Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) (?! Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) (?<= Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) (?<! Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) Quantifier :: QuantifierPrefix QuantifierPrefix ? QuantifierPrefix :: * + ? { DecimalDigits[~Sep] } { DecimalDigits[~Sep] ,} { DecimalDigits[~Sep] , DecimalDigits[~Sep] } Atom[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: PatternCharacter . \ AtomEscape[?UnicodeMode, ?NamedCaptureGroups] CharacterClass[?UnicodeMode, ?UnicodeSetsMode] ( GroupSpecifier[?UnicodeMode]opt Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) (? RegularExpressionModifiers : Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) (? RegularExpressionModifiers - RegularExpressionModifiers : Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) RegularExpressionModifiers :: [empty] RegularExpressionModifiers RegularExpressionModifier RegularExpressionModifier :: one of i m s SyntaxCharacter :: one of ^ $ \ . * + ? ( ) [ ] { } | PatternCharacter :: SourceCharacter but not SyntaxCharacter AtomEscape[UnicodeMode, NamedCaptureGroups] :: DecimalEscape CharacterClassEscape[?UnicodeMode] CharacterEscape[?UnicodeMode] [+NamedCaptureGroups] k GroupName[?UnicodeMode] CharacterEscape[UnicodeMode] :: ControlEscape c AsciiLetter 0 [lookahead ∉ DecimalDigit] HexEscapeSequence RegExpUnicodeEscapeSequence[?UnicodeMode] IdentityEscape[?UnicodeMode] ControlEscape :: one of f n r t v GroupSpecifier[UnicodeMode] :: ? GroupName[?UnicodeMode] GroupName[UnicodeMode] :: < RegExpIdentifierName[?UnicodeMode] > RegExpIdentifierName[UnicodeMode] :: RegExpIdentifierStart[?UnicodeMode] RegExpIdentifierName[?UnicodeMode] RegExpIdentifierPart[?UnicodeMode] RegExpIdentifierStart[UnicodeMode] :: IdentifierStartChar \ RegExpUnicodeEscapeSequence[+UnicodeMode] [~UnicodeMode] UnicodeLeadSurrogate UnicodeTrailSurrogate RegExpIdentifierPart[UnicodeMode] :: IdentifierPartChar \ RegExpUnicodeEscapeSequence[+UnicodeMode] [~UnicodeMode] UnicodeLeadSurrogate UnicodeTrailSurrogate RegExpUnicodeEscapeSequence[UnicodeMode] :: [+UnicodeMode] u HexLeadSurrogate \u HexTrailSurrogate [+UnicodeMode] u HexLeadSurrogate [+UnicodeMode] u HexTrailSurrogate [+UnicodeMode] u HexNonSurrogate [~UnicodeMode] u Hex4Digits [+UnicodeMode] u{ CodePoint } UnicodeLeadSurrogate :: any Unicode code point in the inclusive interval from U+D800 to U+DBFF UnicodeTrailSurrogate :: any Unicode code point in the inclusive interval from U+DC00 to U+DFFF

Each \u HexTrailSurrogate for which the choice of associated u HexLeadSurrogate is ambiguous shall be associated with the nearest possible u HexLeadSurrogate that would otherwise have no corresponding \u HexTrailSurrogate.

HexLeadSurrogate :: Hex4Digits but only if the MV of Hex4Digits is in the inclusive interval from 0xD800 to 0xDBFF HexTrailSurrogate :: Hex4Digits but only if the MV of Hex4Digits is in the inclusive interval from 0xDC00 to 0xDFFF HexNonSurrogate :: Hex4Digits but only if the MV of Hex4Digits is not in the inclusive interval from 0xD800 to 0xDFFF IdentityEscape[UnicodeMode] :: [+UnicodeMode] SyntaxCharacter [+UnicodeMode] / [~UnicodeMode] SourceCharacter but not UnicodeIDContinue DecimalEscape :: NonZeroDigit DecimalDigits[~Sep]opt [lookahead ∉ DecimalDigit] CharacterClassEscape[UnicodeMode] :: d D s S w W [+UnicodeMode] p{ UnicodePropertyValueExpression } [+UnicodeMode] P{ UnicodePropertyValueExpression } UnicodePropertyValueExpression :: UnicodePropertyName = UnicodePropertyValue LoneUnicodePropertyNameOrValue UnicodePropertyName :: UnicodePropertyNameCharacters UnicodePropertyNameCharacters :: UnicodePropertyNameCharacter UnicodePropertyNameCharactersopt UnicodePropertyValue :: UnicodePropertyValueCharacters LoneUnicodePropertyNameOrValue :: UnicodePropertyValueCharacters UnicodePropertyValueCharacters :: UnicodePropertyValueCharacter UnicodePropertyValueCharactersopt UnicodePropertyValueCharacter :: UnicodePropertyNameCharacter DecimalDigit UnicodePropertyNameCharacter :: AsciiLetter _ CharacterClass[UnicodeMode, UnicodeSetsMode] :: [ [lookahead ≠ ^] ClassContents[?UnicodeMode, ?UnicodeSetsMode] ] [^ ClassContents[?UnicodeMode, ?UnicodeSetsMode] ] ClassContents[UnicodeMode, UnicodeSetsMode] :: [empty] [~UnicodeSetsMode] NonemptyClassRanges[?UnicodeMode] [+UnicodeSetsMode] ClassSetExpression NonemptyClassRanges[UnicodeMode] :: ClassAtom[?UnicodeMode] ClassAtom[?UnicodeMode] NonemptyClassRangesNoDash[?UnicodeMode] ClassAtom[?UnicodeMode] - ClassAtom[?UnicodeMode] ClassContents[?UnicodeMode, ~UnicodeSetsMode] NonemptyClassRangesNoDash[UnicodeMode] :: ClassAtom[?UnicodeMode] ClassAtomNoDash[?UnicodeMode] NonemptyClassRangesNoDash[?UnicodeMode] ClassAtomNoDash[?UnicodeMode] - ClassAtom[?UnicodeMode] ClassContents[?UnicodeMode, ~UnicodeSetsMode] ClassAtom[UnicodeMode] :: - ClassAtomNoDash[?UnicodeMode] ClassAtomNoDash[UnicodeMode] :: SourceCharacter but not one of \ or ] or - \ ClassEscape[?UnicodeMode] ClassEscape[UnicodeMode] :: b [+UnicodeMode] - CharacterClassEscape[?UnicodeMode] CharacterEscape[?UnicodeMode] ClassSetExpression :: ClassUnion ClassIntersection ClassSubtraction ClassUnion :: ClassSetRange ClassUnionopt ClassSetOperand ClassUnionopt ClassIntersection :: ClassSetOperand && [lookahead ≠ &] ClassSetOperand ClassIntersection && [lookahead ≠ &] ClassSetOperand ClassSubtraction :: ClassSetOperand -- ClassSetOperand ClassSubtraction -- ClassSetOperand ClassSetRange :: ClassSetCharacter - ClassSetCharacter ClassSetOperand :: NestedClass ClassStringDisjunction ClassSetCharacter NestedClass :: [ [lookahead ≠ ^] ClassContents[+UnicodeMode, +UnicodeSetsMode] ] [^ ClassContents[+UnicodeMode, +UnicodeSetsMode] ] \ CharacterClassEscape[+UnicodeMode] Note 1

The first two lines here are equivalent to CharacterClass.

ClassStringDisjunction :: \q{ ClassStringDisjunctionContents } ClassStringDisjunctionContents :: ClassString ClassString | ClassStringDisjunctionContents ClassString :: [empty] NonEmptyClassString NonEmptyClassString :: ClassSetCharacter NonEmptyClassStringopt ClassSetCharacter :: [lookahead ∉ ClassSetReservedDoublePunctuator] SourceCharacter but not ClassSetSyntaxCharacter \ CharacterEscape[+UnicodeMode] \ ClassSetReservedPunctuator \b ClassSetReservedDoublePunctuator :: one of && !! ## $$ %% ** ++ ,, .. :: ;; << == >> ?? @@ ^^ `` ~~ ClassSetSyntaxCharacter :: one of ( ) [ ] { } / - \ | ClassSetReservedPunctuator :: one of & - ! # % , : ; < = > @ ` ~ Note 2

A number of productions in this section are given alternative definitions in section B.1.2.

22.2.1.1 Static Semantics: Early Errors

Note

This section is amended in B.1.2.1.

Pattern :: Disjunction QuantifierPrefix :: { DecimalDigits , DecimalDigits } Atom :: (? RegularExpressionModifiers : Disjunction ) Atom :: (? RegularExpressionModifiers - RegularExpressionModifiers : Disjunction ) AtomEscape :: k GroupName AtomEscape :: DecimalEscape NonemptyClassRanges :: ClassAtom - ClassAtom ClassContents NonemptyClassRangesNoDash :: ClassAtomNoDash - ClassAtom ClassContents RegExpIdentifierStart :: \ RegExpUnicodeEscapeSequence RegExpIdentifierStart :: UnicodeLeadSurrogate UnicodeTrailSurrogate RegExpIdentifierPart :: \ RegExpUnicodeEscapeSequence RegExpIdentifierPart :: UnicodeLeadSurrogate UnicodeTrailSurrogate UnicodePropertyValueExpression :: UnicodePropertyName = UnicodePropertyValue UnicodePropertyValueExpression :: LoneUnicodePropertyNameOrValue CharacterClassEscape :: P{ UnicodePropertyValueExpression } CharacterClass :: [^ ClassContents ] NestedClass :: [^ ClassContents ] ClassSetRange :: ClassSetCharacter - ClassSetCharacter

22.2.1.2 Static Semantics: CountLeftCapturingParensWithin ( node )

The abstract operation CountLeftCapturingParensWithin takes argument node (a Parse Node) and returns a non-negative integer. It returns the number of left-capturing parentheses in node. A left-capturing parenthesis is any ( pattern character that is matched by the ( terminal of the Atom :: ( GroupSpecifieropt Disjunction ) production.

Note

This section is amended in B.1.2.2.

It performs the following steps when called:

  1. Assert: node is an instance of a production in the RegExp Pattern grammar.
  2. Return the number of Atom :: ( GroupSpecifieropt Disjunction ) Parse Nodes contained within node.

22.2.1.3 Static Semantics: CountLeftCapturingParensBefore ( node )

The abstract operation CountLeftCapturingParensBefore takes argument node (a Parse Node) and returns a non-negative integer. It returns the number of left-capturing parentheses within the enclosing pattern that occur to the left of node.

Note

This section is amended in B.1.2.2.

It performs the following steps when called:

  1. Assert: node is an instance of a production in the RegExp Pattern grammar.
  2. Let pattern be the Pattern containing node.
  3. Return the number of Atom :: ( GroupSpecifieropt Disjunction ) Parse Nodes contained within pattern that either occur before node or contain node.

22.2.1.4 Static Semantics: MightBothParticipate ( x, y )

The abstract operation MightBothParticipate takes arguments x (a Parse Node) and y (a Parse Node) and returns a Boolean. It performs the following steps when called:

  1. Assert: x and y have the same enclosing Pattern.
  2. If the enclosing Pattern contains a Disjunction :: Alternative | Disjunction Parse Node such that either x is contained within the Alternative and y is contained within the derived Disjunction, or x is contained within the derived Disjunction and y is contained within the Alternative, return false.
  3. Return true.

22.2.1.5 Static Semantics: CapturingGroupNumber

The syntax-directed operation CapturingGroupNumber takes no arguments and returns a positive integer.

Note

This section is amended in B.1.2.1.

It is defined piecewise over the following productions:

DecimalEscape :: NonZeroDigit
  1. Return the MV of NonZeroDigit.
DecimalEscape :: NonZeroDigit DecimalDigits
  1. Let n be the number of code points in DecimalDigits.
  2. Return (the MV of NonZeroDigit × 10n plus the MV of DecimalDigits).

The definitions of “the MV of NonZeroDigit” and “the MV of DecimalDigits” are in 12.9.3.

22.2.1.6 Static Semantics: IsCharacterClass

The syntax-directed operation IsCharacterClass takes no arguments and returns a Boolean.

Note

This section is amended in B.1.2.3.

It is defined piecewise over the following productions:

ClassAtom :: - ClassAtomNoDash :: SourceCharacter but not one of \ or ] or - ClassEscape :: b - CharacterEscape
  1. Return false.
ClassEscape :: CharacterClassEscape
  1. Return true.

22.2.1.7 Static Semantics: CharacterValue

The syntax-directed operation CharacterValue takes no arguments and returns a non-negative integer.

Note 1

This section is amended in B.1.2.4.

It is defined piecewise over the following productions:

ClassAtom :: -
  1. Return the numeric value of U+002D (HYPHEN-MINUS).
ClassAtomNoDash :: SourceCharacter but not one of \ or ] or -
  1. Let ch be the code point matched by SourceCharacter.
  2. Return the numeric value of ch.
ClassEscape :: b
  1. Return the numeric value of U+0008 (BACKSPACE).
ClassEscape :: -
  1. Return the numeric value of U+002D (HYPHEN-MINUS).
CharacterEscape :: ControlEscape
  1. Return the numeric value according to Table 67.
Table 67: ControlEscape Code Point Values
ControlEscape Numeric Value Code Point Unicode Name Symbol
t 9 U+0009 CHARACTER TABULATION <HT>
n 10 U+000A LINE FEED (LF) <LF>
v 11 U+000B LINE TABULATION <VT>
f 12 U+000C FORM FEED (FF) <FF>
r 13 U+000D CARRIAGE RETURN (CR) <CR>
CharacterEscape :: c AsciiLetter
  1. Let ch be the code point matched by AsciiLetter.
  2. Let i be the numeric value of ch.
  3. Return the remainder of dividing i by 32.
CharacterEscape :: 0 [lookahead ∉ DecimalDigit]
  1. Return the numeric value of U+0000 (NULL).
Note 2

\0 represents the <NUL> character and cannot be followed by a decimal digit.

CharacterEscape :: HexEscapeSequence
  1. Return the MV of HexEscapeSequence.
RegExpUnicodeEscapeSequence :: u HexLeadSurrogate \u HexTrailSurrogate
  1. Let lead be the CharacterValue of HexLeadSurrogate.
  2. Let trail be the CharacterValue of HexTrailSurrogate.
  3. Let cp be UTF16SurrogatePairToCodePoint(lead, trail).
  4. Return the numeric value of cp.
RegExpUnicodeEscapeSequence :: u Hex4Digits
  1. Return the MV of Hex4Digits.
RegExpUnicodeEscapeSequence :: u{ CodePoint }
  1. Return the MV of CodePoint.
HexLeadSurrogate :: Hex4Digits HexTrailSurrogate :: Hex4Digits HexNonSurrogate :: Hex4Digits
  1. Return the MV of Hex4Digits.
CharacterEscape :: IdentityEscape
  1. Let ch be the code point matched by IdentityEscape.
  2. Return the numeric value of ch.
ClassSetCharacter :: SourceCharacter but not ClassSetSyntaxCharacter
  1. Let ch be the code point matched by SourceCharacter.
  2. Return the numeric value of ch.
ClassSetCharacter :: \ ClassSetReservedPunctuator
  1. Let ch be the code point matched by ClassSetReservedPunctuator.
  2. Return the numeric value of ch.
ClassSetCharacter :: \b
  1. Return the numeric value of U+0008 (BACKSPACE).

22.2.1.8 Static Semantics: MayContainStrings

The syntax-directed operation MayContainStrings takes no arguments and returns a Boolean. It is defined piecewise over the following productions:

CharacterClassEscape :: d D s S w W P{ UnicodePropertyValueExpression } UnicodePropertyValueExpression :: UnicodePropertyName = UnicodePropertyValue NestedClass :: [^ ClassContents ] ClassContents :: [empty] NonemptyClassRanges ClassSetOperand :: ClassSetCharacter
  1. Return false.
UnicodePropertyValueExpression :: LoneUnicodePropertyNameOrValue
  1. If the source text matched by LoneUnicodePropertyNameOrValue is a binary property of strings listed in the “Property name” column of Table 71, return true.
  2. Return false.
ClassUnion :: ClassSetRange ClassUnionopt
  1. If the ClassUnion is present, return MayContainStrings of the ClassUnion.
  2. Return false.
ClassUnion :: ClassSetOperand ClassUnionopt
  1. If MayContainStrings of the ClassSetOperand is true, return true.
  2. If ClassUnion is present, return MayContainStrings of the ClassUnion.
  3. Return false.
ClassIntersection :: ClassSetOperand && ClassSetOperand
  1. If MayContainStrings of the first ClassSetOperand is false, return false.
  2. If MayContainStrings of the second ClassSetOperand is false, return false.
  3. Return true.
ClassIntersection :: ClassIntersection && ClassSetOperand
  1. If MayContainStrings of the ClassIntersection is false, return false.
  2. If MayContainStrings of the ClassSetOperand is false, return false.
  3. Return true.
ClassSubtraction :: ClassSetOperand -- ClassSetOperand
  1. Return MayContainStrings of the first ClassSetOperand.
ClassSubtraction :: ClassSubtraction -- ClassSetOperand
  1. Return MayContainStrings of the ClassSubtraction.
ClassStringDisjunctionContents :: ClassString | ClassStringDisjunctionContents
  1. If MayContainStrings of the ClassString is true, return true.
  2. Return MayContainStrings of the ClassStringDisjunctionContents.
ClassString :: [empty]
  1. Return true.
ClassString :: NonEmptyClassString
  1. Return MayContainStrings of the NonEmptyClassString.
NonEmptyClassString :: ClassSetCharacter NonEmptyClassStringopt
  1. If NonEmptyClassString is present, return true.
  2. Return false.

22.2.1.9 Static Semantics: GroupSpecifiersThatMatch ( thisGroupName )

The abstract operation GroupSpecifiersThatMatch takes argument thisGroupName (a GroupName Parse Node) and returns a List of GroupSpecifier Parse Nodes. It performs the following steps when called:

  1. Let name be the CapturingGroupName of thisGroupName.
  2. Let pattern be the Pattern containing thisGroupName.
  3. Let result be a new empty List.
  4. For each GroupSpecifier gs that pattern contains, do
    1. If the CapturingGroupName of gs is name, then
      1. Append gs to result.
  5. Return result.

22.2.1.10 Static Semantics: CapturingGroupName

The syntax-directed operation CapturingGroupName takes no arguments and returns a String. It is defined piecewise over the following productions:

GroupName :: < RegExpIdentifierName >
  1. Let idTextUnescaped be the RegExpIdentifierCodePoints of RegExpIdentifierName.
  2. Return CodePointsToString(idTextUnescaped).

22.2.1.11 Static Semantics: RegExpIdentifierCodePoints

The syntax-directed operation RegExpIdentifierCodePoints takes no arguments and returns a List of code points. It is defined piecewise over the following productions:

RegExpIdentifierName :: RegExpIdentifierStart
  1. Let cp be the RegExpIdentifierCodePoint of RegExpIdentifierStart.
  2. Return « cp ».
RegExpIdentifierName :: RegExpIdentifierName RegExpIdentifierPart
  1. Let cps be the RegExpIdentifierCodePoints of the derived RegExpIdentifierName.
  2. Let cp be the RegExpIdentifierCodePoint of RegExpIdentifierPart.
  3. Return the list-concatenation of cps and « cp ».

22.2.1.12 Static Semantics: RegExpIdentifierCodePoint

The syntax-directed operation RegExpIdentifierCodePoint takes no arguments and returns a code point. It is defined piecewise over the following productions:

RegExpIdentifierStart :: IdentifierStartChar
  1. Return the code point matched by IdentifierStartChar.
RegExpIdentifierPart :: IdentifierPartChar
  1. Return the code point matched by IdentifierPartChar.
RegExpIdentifierStart :: \ RegExpUnicodeEscapeSequence RegExpIdentifierPart :: \ RegExpUnicodeEscapeSequence
  1. Return the code point whose numeric value is the CharacterValue of RegExpUnicodeEscapeSequence.
RegExpIdentifierStart :: UnicodeLeadSurrogate UnicodeTrailSurrogate RegExpIdentifierPart :: UnicodeLeadSurrogate UnicodeTrailSurrogate
  1. Let lead be the code unit whose numeric value is the numeric value of the code point matched by UnicodeLeadSurrogate.
  2. Let trail be the code unit whose numeric value is the numeric value of the code point matched by UnicodeTrailSurrogate.
  3. Return UTF16SurrogatePairToCodePoint(lead, trail).

22.2.2 Pattern Semantics

A regular expression pattern is converted into an Abstract Closure using the process described below. An implementation is encouraged to use more efficient algorithms than the ones listed below, as long as the results are the same. The Abstract Closure is used as the value of a RegExp object's [[RegExpMatcher]] internal slot.

A Pattern is a BMP pattern if its associated flags contain neither a u nor a v. Otherwise, it is a Unicode pattern. A BMP pattern matches against a String interpreted as consisting of a sequence of 16-bit values that are Unicode code points in the range of the Basic Multilingual Plane. A Unicode pattern matches against a String interpreted as consisting of Unicode code points encoded using UTF-16. In the context of describing the behaviour of a BMP pattern “character” means a single 16-bit Unicode BMP code point. In the context of describing the behaviour of a Unicode pattern “character” means a UTF-16 encoded code point (6.1.4). In either context, “character value” means the numeric value of the corresponding non-encoded code point.

The syntax and semantics of Pattern is defined as if the source text for the Pattern was a List of SourceCharacter values where each SourceCharacter corresponds to a Unicode code point. If a BMP pattern contains a non-BMP SourceCharacter the entire pattern is encoded using UTF-16 and the individual code units of that encoding are used as the elements of the List.

Note

For example, consider a pattern expressed in source text as the single non-BMP character U+1D11E (MUSICAL SYMBOL G CLEF). Interpreted as a Unicode pattern, it would be a single element (character) List consisting of the single code point U+1D11E. However, interpreted as a BMP pattern, it is first UTF-16 encoded to produce a two element List consisting of the code units 0xD834 and 0xDD1E.

Patterns are passed to the RegExp constructor as ECMAScript String values in which non-BMP characters are UTF-16 encoded. For example, the single character MUSICAL SYMBOL G CLEF pattern, expressed as a String value, is a String of length 2 whose elements were the code units 0xD834 and 0xDD1E. So no further translation of the string would be necessary to process it as a BMP pattern consisting of two pattern characters. However, to process it as a Unicode pattern UTF16SurrogatePairToCodePoint must be used in producing a List whose sole element is a single pattern character, the code point U+1D11E.

An implementation may not actually perform such translations to or from UTF-16, but the semantics of this specification requires that the result of pattern matching be as if such translations were performed.

22.2.2.1 Notation

The descriptions below use the following internal data structures:

  • A CharSetElement is one of the two following entities:
    • If rer.[[UnicodeSets]] is false, then a CharSetElement is a character in the sense of the Pattern Semantics above.
    • If rer.[[UnicodeSets]] is true, then a CharSetElement is a sequence whose elements are characters in the sense of the Pattern Semantics above. This includes the empty sequence, sequences of one character, and sequences of more than one character. For convenience, when working with CharSetElements of this kind, an individual character is treated interchangeably with a sequence of one character.
  • A CharSet is a mathematical set of CharSetElements.
  • A CaptureRange is a Record { [[StartIndex]], [[EndIndex]] } that represents the range of characters included in a capture, where [[StartIndex]] is an integer representing the start index (inclusive) of the range within Input, and [[EndIndex]] is an integer representing the end index (exclusive) of the range within Input. For any CaptureRange, these indices must satisfy the invariant that [[StartIndex]][[EndIndex]].
  • A MatchState is a Record { [[Input]], [[EndIndex]], [[Captures]] } where [[Input]] is a List of characters representing the String being matched, [[EndIndex]] is an integer, and [[Captures]] is a List of values, one for each left-capturing parenthesis in the pattern. MatchStates are used to represent partial match states in the regular expression matching algorithms. The [[EndIndex]] is one plus the index of the last input character matched so far by the pattern, while [[Captures]] holds the results of capturing parentheses. The nth element of [[Captures]] is either a CaptureRange representing the range of characters captured by the nth set of capturing parentheses, or undefined if the nth set of capturing parentheses hasn't been reached yet. Due to backtracking, many MatchStates may be in use at any time during the matching process.
  • A MatcherContinuation is an Abstract Closure that takes one MatchState argument and returns either a MatchState or failure. The MatcherContinuation attempts to match the remaining portion (specified by the closure's captured values) of the pattern against Input, starting at the intermediate state given by its MatchState argument. If the match succeeds, the MatcherContinuation returns the final MatchState that it reached; if the match fails, the MatcherContinuation returns failure.
  • A Matcher is an Abstract Closure that takes two arguments—a MatchState and a MatcherContinuation—and returns either a MatchState or failure. A Matcher attempts to match a middle subpattern (specified by the closure's captured values) of the pattern against the MatchState's [[Input]], starting at the intermediate state given by its MatchState argument. The MatcherContinuation argument should be a closure that matches the rest of the pattern. After matching the subpattern of a pattern to obtain a new MatchState, the Matcher then calls MatcherContinuation on that new MatchState to test if the rest of the pattern can match as well. If it can, the Matcher returns the MatchState returned by MatcherContinuation; if not, the Matcher may try different choices at its choice points, repeatedly calling MatcherContinuation until it either succeeds or all possibilities have been exhausted.

22.2.2.1.1 RegExp Records

A RegExp Record is a Record value used to store information about a RegExp that is needed during compilation and possibly during matching.

It has the following fields:

Table 68: RegExp Record Fields
Field Name Value Meaning
[[IgnoreCase]] a Boolean indicates whether "i" appears in the RegExp's flags
[[Multiline]] a Boolean indicates whether "m" appears in the RegExp's flags
[[DotAll]] a Boolean indicates whether "s" appears in the RegExp's flags
[[Unicode]] a Boolean indicates whether "u" appears in the RegExp's flags
[[UnicodeSets]] a Boolean indicates whether "v" appears in the RegExp's flags
[[CapturingGroupsCount]] a non-negative integer the number of left-capturing parentheses in the RegExp's pattern

22.2.2.2 Runtime Semantics: CompilePattern

The syntax-directed operation CompilePattern takes argument rer (a RegExp Record) and returns an Abstract Closure that takes a List of characters and a non-negative integer and returns either a MatchState or failure. It is defined piecewise over the following productions:

Pattern :: Disjunction
  1. Let m be CompileSubpattern of Disjunction with arguments rer and forward.
  2. Return a new Abstract Closure with parameters (Input, index) that captures rer and m and performs the following steps when called:
    1. Assert: Input is a List of characters.
    2. Assert: 0 ≤ index ≤ the number of elements in Input.
    3. Let c be a new MatcherContinuation with parameters (y) that captures nothing and performs the following steps when called:
      1. Assert: y is a MatchState.
      2. Return y.
    4. Let cap be a List of rer.[[CapturingGroupsCount]] undefined values, indexed 1 through rer.[[CapturingGroupsCount]].
    5. Let x be the MatchState { [[Input]]: Input, [[EndIndex]]: index, [[Captures]]: cap }.
    6. Return m(x, c).
Note

A Pattern compiles to an Abstract Closure value. RegExpBuiltinExec can then apply this procedure to a List of characters and an offset within that List to determine whether the pattern would match starting at exactly that offset within the List, and, if it does match, what the values of the capturing parentheses would be. The algorithms in 22.2.2 are designed so that compiling a pattern may throw a SyntaxError exception; on the other hand, once the pattern is successfully compiled, applying the resulting Abstract Closure to find a match in a List of characters cannot throw an exception (except for any implementation-defined exceptions that can occur anywhere such as out-of-memory).

22.2.2.3 Runtime Semantics: CompileSubpattern

The syntax-directed operation CompileSubpattern takes arguments rer (a RegExp Record) and direction (forward or backward) and returns a Matcher.

Note 1

This section is amended in B.1.2.5.

It is defined piecewise over the following productions:

Disjunction :: Alternative | Disjunction
  1. Let m1 be CompileSubpattern of Alternative with arguments rer and direction.
  2. Let m2 be CompileSubpattern of Disjunction with arguments rer and direction.
  3. Return MatchTwoAlternatives(m1, m2).
Note 2

The | regular expression operator separates two alternatives. The pattern first tries to match the left Alternative (followed by the sequel of the regular expression); if it fails, it tries to match the right Disjunction (followed by the sequel of the regular expression). If the left Alternative, the right Disjunction, and the sequel all have choice points, all choices in the sequel are tried before moving on to the next choice in the left Alternative. If choices in the left Alternative are exhausted, the right Disjunction is tried instead of the left Alternative. Any capturing parentheses inside a portion of the pattern skipped by | produce undefined values instead of Strings. Thus, for example,

/a|ab/.exec("abc")

returns the result "a" and not "ab". Moreover,

/((a)|(ab))((c)|(bc))/.exec("abc")

returns the array

["abc", "a", "a", undefined, "bc", undefined, "bc"]

and not

["abc", "ab", undefined, "ab", "c", "c", undefined]

The order in which the two alternatives are tried is independent of the value of direction.

Alternative :: [empty]
  1. Return EmptyMatcher().
Alternative :: Alternative Term
  1. Let m1 be CompileSubpattern of Alternative with arguments rer and direction.
  2. Let m2 be CompileSubpattern of Term with arguments rer and direction.
  3. Return MatchSequence(m1, m2, direction).
Note 3

Consecutive Terms try to simultaneously match consecutive portions of Input. When direction is forward, if the left Alternative, the right Term, and the sequel of the regular expression all have choice points, all choices in the sequel are tried before moving on to the next choice in the right Term, and all choices in the right Term are tried before moving on to the next choice in the left Alternative. When direction is backward, the evaluation order of Alternative and Term are reversed.

Term :: Assertion
  1. Return CompileAssertion of Assertion with argument rer.
Note 4

The resulting Matcher is independent of direction.

Term :: Atom
  1. Return CompileAtom of Atom with arguments rer and direction.
Term :: Atom Quantifier
  1. Let m be CompileAtom of Atom with arguments rer and direction.
  2. Let q be CompileQuantifier of Quantifier.
  3. Assert: q.[[Min]]q.[[Max]].
  4. Let parenIndex be CountLeftCapturingParensBefore(Term).
  5. Let parenCount be CountLeftCapturingParensWithin(Atom).
  6. Return a new Matcher with parameters (x, c) that captures m, q, parenIndex, and parenCount and performs the following steps when called:
    1. Assert: x is a MatchState.
    2. Assert: c is a MatcherContinuation.
    3. Return RepeatMatcher(m, q.[[Min]], q.[[Max]], q.[[Greedy]], x, c, parenIndex, parenCount).

22.2.2.3.1 RepeatMatcher ( m, min, max, greedy, x, c, parenIndex, parenCount )

The abstract operation RepeatMatcher takes arguments m (a Matcher), min (a non-negative integer), max (a non-negative integer or +∞), greedy (a Boolean), x (a MatchState), c (a MatcherContinuation), parenIndex (a non-negative integer), and parenCount (a non-negative integer) and returns either a MatchState or failure. It performs the following steps when called:

  1. If max = 0, return c(x).
  2. Let d be a new MatcherContinuation with parameters (y) that captures m, min, max, greedy, x, c, parenIndex, and parenCount and performs the following steps when called:
    1. Assert: y is a MatchState.
    2. If min = 0 and y.[[EndIndex]] = x.[[EndIndex]], return failure.
    3. If min = 0, let min2 be 0; otherwise let min2 be min - 1.
    4. If max = +∞, let max2 be +∞; otherwise let max2 be max - 1.
    5. Return RepeatMatcher(m, min2, max2, greedy, y, c, parenIndex, parenCount).
  3. Let cap be a copy of x.[[Captures]].
  4. For each integer k in the inclusive interval from parenIndex + 1 to parenIndex + parenCount, set cap[k] to undefined.
  5. Let Input be x.[[Input]].
  6. Let e be x.[[EndIndex]].
  7. Let xr be the MatchState { [[Input]]: Input, [[EndIndex]]: e, [[Captures]]: cap }.
  8. If min ≠ 0, return m(xr, d).
  9. If greedy is false, then
    1. Let z be c(x).
    2. If z is not failure, return z.
    3. Return m(xr, d).
  10. Let z be m(xr, d).
  11. If z is not failure, return z.
  12. Return c(x).
Note 1

An Atom followed by a Quantifier is repeated the number of times specified by the Quantifier. A Quantifier can be non-greedy, in which case the Atom pattern is repeated as few times as possible while still matching the sequel, or it can be greedy, in which case the Atom pattern is repeated as many times as possible while still matching the sequel. The Atom pattern is repeated rather than the input character sequence that it matches, so different repetitions of the Atom can match different input substrings.

Note 2

If the Atom and the sequel of the regular expression all have choice points, the Atom is first matched as many (or as few, if non-greedy) times as possible. All choices in the sequel are tried before moving on to the next choice in the last repetition of Atom. All choices in the last (nth) repetition of Atom are tried before moving on to the next choice in the next-to-last (n - 1)st repetition of Atom; at which point it may turn out that more or fewer repetitions of Atom are now possible; these are exhausted (again, starting with either as few or as many as possible) before moving on to the next choice in the (n - 1)st repetition of Atom and so on.

Compare

/a[a-z]{2,4}/.exec("abcdefghi")

which returns "abcde" with

/a[a-z]{2,4}?/.exec("abcdefghi")

which returns "abc".

Consider also

/(aa|aabaac|ba|b|c)*/.exec("aabaac")

which, by the choice point ordering above, returns the array

["aaba", "ba"]

and not any of:

["aabaac", "aabaac"]
["aabaac", "c"]

The above ordering of choice points can be used to write a regular expression that calculates the greatest common divisor of two numbers (represented in unary notation). The following example calculates the gcd of 10 and 15:

"aaaaaaaaaa,aaaaaaaaaaaaaaa".replace(/^(a+)\1*,\1+$/, "$1")

which returns the gcd in unary notation "aaaaa".

Note 3

Step 4 of the RepeatMatcher clears Atom's captures each time Atom is repeated. We can see its behaviour in the regular expression

/(z)((a+)?(b+)?(c))*/.exec("zaacbbbcac")

which returns the array

["zaacbbbcac", "z", "ac", "a", undefined, "c"]

and not

["zaacbbbcac", "z", "ac", "a", "bbb", "c"]

because each iteration of the outermost * clears all captured Strings contained in the quantified Atom, which in this case includes capture Strings numbered 2, 3, 4, and 5.

Note 4

Step 2.b of the RepeatMatcher states that once the minimum number of repetitions has been satisfied, any more expansions of Atom that match the empty character sequence are not considered for further repetitions. This prevents the regular expression engine from falling into an infinite loop on patterns such as:

/(a*)*/.exec("b")

or the slightly more complicated:

/(a*)b\1+/.exec("baaaac")

which returns the array

["b", ""]

22.2.2.3.2 EmptyMatcher ( )

The abstract operation EmptyMatcher takes no arguments and returns a Matcher. It performs the following steps when called:

  1. Return a new Matcher with parameters (x, c) that captures nothing and performs the following steps when called:
    1. Assert: x is a MatchState.
    2. Assert: c is a MatcherContinuation.
    3. Return c(x).

22.2.2.3.3 MatchTwoAlternatives ( m1, m2 )

The abstract operation MatchTwoAlternatives takes arguments m1 (a Matcher) and m2 (a Matcher) and returns a Matcher. It performs the following steps when called:

  1. Return a new Matcher with parameters (x, c) that captures m1 and m2 and performs the following steps when called:
    1. Assert: x is a MatchState.
    2. Assert: c is a MatcherContinuation.
    3. Let r be m1(x, c).
    4. If r is not failure, return r.
    5. Return m2(x, c).

22.2.2.3.4 MatchSequence ( m1, m2, direction )

The abstract operation MatchSequence takes arguments m1 (a Matcher), m2 (a Matcher), and direction (forward or backward) and returns a Matcher. It performs the following steps when called:

  1. If direction is forward, then
    1. Return a new Matcher with parameters (x, c) that captures m1 and m2 and performs the following steps when called:
      1. Assert: x is a MatchState.
      2. Assert: c is a MatcherContinuation.
      3. Let d be a new MatcherContinuation with parameters (y) that captures c and m2 and performs the following steps when called:
        1. Assert: y is a MatchState.
        2. Return m2(y, c).
      4. Return m1(x, d).
  2. Else,
    1. Assert: direction is backward.
    2. Return a new Matcher with parameters (x, c) that captures m1 and m2 and performs the following steps when called:
      1. Assert: x is a MatchState.
      2. Assert: c is a MatcherContinuation.
      3. Let d be a new MatcherContinuation with parameters (y) that captures c and m1 and performs the following steps when called:
        1. Assert: y is a MatchState.
        2. Return m1(y, c).
      4. Return m2(x, d).

22.2.2.4 Runtime Semantics: CompileAssertion

The syntax-directed operation CompileAssertion takes argument rer (a RegExp Record) and returns a Matcher.

Note 1

This section is amended in B.1.2.6.

It is defined piecewise over the following productions:

Assertion :: ^
  1. Return a new Matcher with parameters (x, c) that captures rer and performs the following steps when called:
    1. Assert: x is a MatchState.
    2. Assert: c is a MatcherContinuation.
    3. Let Input be x.[[Input]].
    4. Let e be x.[[EndIndex]].
    5. If e = 0, or if rer.[[Multiline]] is true and the character Input[e - 1] is matched by LineTerminator, then
      1. Return c(x).
    6. Return failure.
Note 2

Even when the y flag is used with a pattern, ^ always matches only at the beginning of Input, or (if rer.[[Multiline]] is true) at the beginning of a line.

Assertion :: $
  1. Return a new Matcher with parameters (x, c) that captures rer and performs the following steps when called:
    1. Assert: x is a MatchState.
    2. Assert: c is a MatcherContinuation.
    3. Let Input be x.[[Input]].
    4. Let e be x.[[EndIndex]].
    5. Let InputLength be the number of elements in Input.
    6. If e = InputLength, or if rer.[[Multiline]] is true and the character Input[e] is matched by LineTerminator, then
      1. Return c(x).
    7. Return failure.
Assertion :: \b
  1. Return a new Matcher with parameters (x, c) that captures rer and performs the following steps when called:
    1. Assert: x is a MatchState.
    2. Assert: c is a MatcherContinuation.
    3. Let Input be x.[[Input]].
    4. Let e be x.[[EndIndex]].
    5. Let a be IsWordChar(rer, Input, e - 1).
    6. Let b be IsWordChar(rer, Input, e).
    7. If a is true and b is false, or if a is false and b is true, return c(x).
    8. Return failure.
Assertion :: \B
  1. Return a new Matcher with parameters (x, c) that captures rer and performs the following steps when called:
    1. Assert: x is a MatchState.
    2. Assert: c is a MatcherContinuation.
    3. Let Input be x.[[Input]].
    4. Let e be x.[[EndIndex]].
    5. Let a be IsWordChar(rer, Input, e - 1).
    6. Let b be IsWordChar(rer, Input, e).
    7. If a is true and b is true, or if a is false and b is false, return c(x).
    8. Return failure.
Assertion :: (?= Disjunction )
  1. Let m be CompileSubpattern of Disjunction with arguments rer and forward.
  2. Return a new Matcher with parameters (x, c) that captures m and performs the following steps when called:
    1. Assert: x is a MatchState.
    2. Assert: c is a MatcherContinuation.
    3. Let d be a new MatcherContinuation with parameters (y) that captures nothing and performs the following steps when called:
      1. Assert: y is a MatchState.
      2. Return y.
    4. Let r be m(x, d).
    5. If r is failure, return failure.
    6. Assert: r is a MatchState.
    7. Let cap be r.[[Captures]].
    8. Let Input be x.[[Input]].
    9. Let xe be x.[[EndIndex]].
    10. Let z be the MatchState { [[Input]]: Input, [[EndIndex]]: xe, [[Captures]]: cap }.
    11. Return c(z).
Note 3

The form (?= Disjunction ) specifies a zero-width positive lookahead. In order for it to succeed, the pattern inside Disjunction must match at the current position, but the current position is not advanced before matching the sequel. If Disjunction can match at the current position in several ways, only the first one is tried. Unlike other regular expression operators, there is no backtracking into a (?= form (this unusual behaviour is inherited from Perl). This only matters when the Disjunction contains capturing parentheses and the sequel of the pattern contains backreferences to those captures.

For example,

/(?=(a+))/.exec("baaabac")

matches the empty String immediately after the first b and therefore returns the array:

["", "aaa"]

To illustrate the lack of backtracking into the lookahead, consider:

/(?=(a+))a*b\1/.exec("baaabac")

This expression returns

["aba", "a"]

and not:

["aaaba", "a"]
Assertion :: (?! Disjunction )
  1. Let m be CompileSubpattern of Disjunction with arguments rer and forward.
  2. Return a new Matcher with parameters (x, c) that captures m and performs the following steps when called:
    1. Assert: x is a MatchState.
    2. Assert: c is a MatcherContinuation.
    3. Let d be a new MatcherContinuation with parameters (y) that captures nothing and performs the following steps when called:
      1. Assert: y is a MatchState.
      2. Return y.
    4. Let r be m(x, d).
    5. If r is not failure, return failure.
    6. Return c(x).
Note 4

The form (?! Disjunction ) specifies a zero-width negative lookahead. In order for it to succeed, the pattern inside Disjunction must fail to match at the current position. The current position is not advanced before matching the sequel. Disjunction can contain capturing parentheses, but backreferences to them only make sense from within Disjunction itself. Backreferences to these capturing parentheses from elsewhere in the pattern always return undefined because the negative lookahead must fail for the pattern to succeed. For example,

/(.*?)a(?!(a+)b\2c)\2(.*)/.exec("baaabaac")

looks for an a not immediately followed by some positive number n of a's, a b, another n a's (specified by the first \2) and a c. The second \2 is outside the negative lookahead, so it matches against undefined and therefore always succeeds. The whole expression returns the array:

["baaabaac", "ba", undefined, "abaac"]
Assertion :: (?<= Disjunction )
  1. Let m be CompileSubpattern of Disjunction with arguments rer and backward.
  2. Return a new Matcher with parameters (x, c) that captures m and performs the following steps when called:
    1. Assert: x is a MatchState.
    2. Assert: c is a MatcherContinuation.
    3. Let d be a new MatcherContinuation with parameters (y) that captures nothing and performs the following steps when called:
      1. Assert: y is a MatchState.
      2. Return y.
    4. Let r be m(x, d).
    5. If r is failure, return failure.
    6. Assert: r is a MatchState.
    7. Let cap be r.[[Captures]].
    8. Let Input be x.[[Input]].
    9. Let xe be x.[[EndIndex]].
    10. Let z be the MatchState { [[Input]]: Input, [[EndIndex]]: xe, [[Captures]]: cap }.
    11. Return c(z).
Assertion :: (?<! Disjunction )
  1. Let m be CompileSubpattern of Disjunction with arguments rer and backward.
  2. Return a new Matcher with parameters (x, c) that captures m and performs the following steps when called:
    1. Assert: x is a MatchState.
    2. Assert: c is a MatcherContinuation.
    3. Let d be a new MatcherContinuation with parameters (y) that captures nothing and performs the following steps when called:
      1. Assert: y is a MatchState.
      2. Return y.
    4. Let r be m(x, d).
    5. If r is not failure, return failure.
    6. Return c(x).

22.2.2.4.1 IsWordChar ( rer, Input, e )

The abstract operation IsWordChar takes arguments rer (a RegExp Record), Input (a List of characters), and e (an integer) and returns a Boolean. It performs the following steps when called:

  1. Let InputLength be the number of elements in Input.
  2. If e = -1 or e = InputLength, return false.
  3. Let c be the character Input[e].
  4. If WordCharacters(rer) contains c, return true.
  5. Return false.

22.2.2.5 Runtime Semantics: CompileQuantifier

The syntax-directed operation CompileQuantifier takes no arguments and returns a Record with fields [[Min]] (a non-negative integer), [[Max]] (a non-negative integer or +∞), and [[Greedy]] (a Boolean). It is defined piecewise over the following productions:

Quantifier :: QuantifierPrefix
  1. Let qp be CompileQuantifierPrefix of QuantifierPrefix.
  2. Return the Record { [[Min]]: qp.[[Min]], [[Max]]: qp.[[Max]], [[Greedy]]: true }.
Quantifier :: QuantifierPrefix ?
  1. Let qp be CompileQuantifierPrefix of QuantifierPrefix.
  2. Return the Record { [[Min]]: qp.[[Min]], [[Max]]: qp.[[Max]], [[Greedy]]: false }.

22.2.2.6 Runtime Semantics: CompileQuantifierPrefix

The syntax-directed operation CompileQuantifierPrefix takes no arguments and returns a Record with fields [[Min]] (a non-negative integer) and [[Max]] (a non-negative integer or +∞). It is defined piecewise over the following productions:

QuantifierPrefix :: *
  1. Return the Record { [[Min]]: 0, [[Max]]: +∞ }.
QuantifierPrefix :: +
  1. Return the Record { [[Min]]: 1, [[Max]]: +∞ }.
QuantifierPrefix :: ?
  1. Return the Record { [[Min]]: 0, [[Max]]: 1 }.
QuantifierPrefix :: { DecimalDigits }
  1. Let i be the MV of DecimalDigits (see 12.9.3).
  2. Return the Record { [[Min]]: i, [[Max]]: i }.
QuantifierPrefix :: { DecimalDigits ,}
  1. Let i be the MV of DecimalDigits.
  2. Return the Record { [[Min]]: i, [[Max]]: +∞ }.
QuantifierPrefix :: { DecimalDigits , DecimalDigits }
  1. Let i be the MV of the first DecimalDigits.
  2. Let j be the MV of the second DecimalDigits.
  3. Return the Record { [[Min]]: i, [[Max]]: j }.

22.2.2.7 Runtime Semantics: CompileAtom

The syntax-directed operation CompileAtom takes arguments rer (a RegExp Record) and direction (forward or backward) and returns a Matcher.

Note 1

This section is amended in B.1.2.7.

It is defined piecewise over the following productions:

Atom :: PatternCharacter
  1. Let ch be the character matched by PatternCharacter.
  2. Let A be a one-element CharSet containing the character ch.
  3. Return CharacterSetMatcher(rer, A, false, direction).
Atom :: .
  1. Let A be AllCharacters(rer).
  2. If rer.[[DotAll]] is not true, then
    1. Remove from A all characters corresponding to a code point on the right-hand side of the LineTerminator production.
  3. Return CharacterSetMatcher(rer, A, false, direction).
Atom :: CharacterClass
  1. Let cc be CompileCharacterClass of CharacterClass with argument rer.
  2. Let cs be cc.[[CharSet]].
  3. If rer.[[UnicodeSets]] is false, or if every CharSetElement of cs consists of a single character (including if cs is empty), return CharacterSetMatcher(rer, cs, cc.[[Invert]], direction).
  4. Assert: cc.[[Invert]] is false.
  5. Let lm be an empty List of Matchers.
  6. For each CharSetElement s in cs containing more than 1 character, iterating in descending order of length, do
    1. Let cs2 be a one-element CharSet containing the last code point of s.
    2. Let m2 be CharacterSetMatcher(rer, cs2, false, direction).
    3. For each code point c1 in s, iterating backwards from its second-to-last code point, do
      1. Let cs1 be a one-element CharSet containing c1.
      2. Let m1 be CharacterSetMatcher(rer, cs1, false, direction).
      3. Set m2 to MatchSequence(m1, m2, direction).
    4. Append m2 to lm.
  7. Let singles be the CharSet containing every CharSetElement of cs that consists of a single character.
  8. Append CharacterSetMatcher(rer, singles, false, direction) to lm.
  9. If cs contains the empty sequence of characters, append EmptyMatcher() to lm.
  10. Let m2 be the last Matcher in lm.
  11. For each Matcher m1 of lm, iterating backwards from its second-to-last element, do
    1. Set m2 to MatchTwoAlternatives(m1, m2).
  12. Return m2.
Atom :: ( GroupSpecifieropt Disjunction )
  1. Let m be CompileSubpattern of Disjunction with arguments rer and direction.
  2. Let parenIndex be CountLeftCapturingParensBefore(Atom).
  3. Return a new Matcher with parameters (x, c) that captures direction, m, and parenIndex and performs the following steps when called:
    1. Assert: x is a MatchState.
    2. Assert: c is a MatcherContinuation.
    3. Let d be a new MatcherContinuation with parameters (y) that captures x, c, direction, and parenIndex and performs the following steps when called:
      1. Assert: y is a MatchState.
      2. Let cap be a copy of y.[[Captures]].
      3. Let Input be x.[[Input]].
      4. Let xe be x.[[EndIndex]].
      5. Let ye be y.[[EndIndex]].
      6. If direction is forward, then
        1. Assert: xeye.
        2. Let r be the CaptureRange { [[StartIndex]]: xe, [[EndIndex]]: ye }.
      7. Else,
        1. Assert: direction is backward.
        2. Assert: yexe.
        3. Let r be the CaptureRange { [[StartIndex]]: ye, [[EndIndex]]: xe }.
      8. Set cap[parenIndex + 1] to r.
      9. Let z be the MatchState { [[Input]]: Input, [[EndIndex]]: ye, [[Captures]]: cap }.
      10. Return c(z).
    4. Return m(x, d).
Note 2

Parentheses of the form ( Disjunction ) serve both to group the components of the Disjunction pattern together and to save the result of the match. The result can be used either in a backreference (\ followed by a non-zero decimal number), referenced in a replace String, or returned as part of an array from the regular expression matching Abstract Closure. To inhibit the capturing behaviour of parentheses, use the form (?: Disjunction ) instead.

Atom :: (? RegularExpressionModifiers : Disjunction )
  1. Let addModifiers be the source text matched by RegularExpressionModifiers.
  2. Let removeModifiers be the empty String.
  3. Let modifiedRer be UpdateModifiers(rer, CodePointsToString(addModifiers), removeModifiers).
  4. Return CompileSubpattern of Disjunction with arguments modifiedRer and direction.
Atom :: (? RegularExpressionModifiers - RegularExpressionModifiers : Disjunction )
  1. Let addModifiers be the source text matched by the first RegularExpressionModifiers.
  2. Let removeModifiers be the source text matched by the second RegularExpressionModifiers.
  3. Let modifiedRer be UpdateModifiers(rer, CodePointsToString(addModifiers), CodePointsToString(removeModifiers)).
  4. Return CompileSubpattern of Disjunction with arguments modifiedRer and direction.
AtomEscape :: DecimalEscape
  1. Let n be the CapturingGroupNumber of DecimalEscape.
  2. Assert: nrer.[[CapturingGroupsCount]].
  3. Return BackreferenceMatcher(rer, « n », direction).
Note 3

An escape sequence of the form \ followed by a non-zero decimal number n matches the result of the nth set of capturing parentheses (22.2.2.1). It is an error if the regular expression has fewer than n capturing parentheses. If the regular expression has n or more capturing parentheses but the nth one is undefined because it has not captured anything, then the backreference always succeeds.

AtomEscape :: CharacterEscape
  1. Let cv be the CharacterValue of CharacterEscape.
  2. Let ch be the character whose character value is cv.
  3. Let A be a one-element CharSet containing the character ch.
  4. Return CharacterSetMatcher(rer, A, false, direction).
AtomEscape :: CharacterClassEscape
  1. Let cs be CompileToCharSet of CharacterClassEscape with argument rer.
  2. If rer.[[UnicodeSets]] is false, or if every CharSetElement of cs consists of a single character (including if cs is empty), return CharacterSetMatcher(rer, cs, false, direction).
  3. Let lm be an empty List of Matchers.
  4. For each CharSetElement s in cs containing more than 1 character, iterating in descending order of length, do
    1. Let cs2 be a one-element CharSet containing the last code point of s.
    2. Let m2 be CharacterSetMatcher(rer, cs2, false, direction).
    3. For each code point c1 in s, iterating backwards from its second-to-last code point, do
      1. Let cs1 be a one-element CharSet containing c1.
      2. Let m1 be CharacterSetMatcher(rer, cs1, false, direction).
      3. Set m2 to MatchSequence(m1, m2, direction).
    4. Append m2 to lm.
  5. Let singles be the CharSet containing every CharSetElement of cs that consists of a single character.
  6. Append CharacterSetMatcher(rer, singles, false, direction) to lm.
  7. If cs contains the empty sequence of characters, append EmptyMatcher() to lm.
  8. Let m2 be the last Matcher in lm.
  9. For each Matcher m1 of lm, iterating backwards from its second-to-last element, do
    1. Set m2 to MatchTwoAlternatives(m1, m2).
  10. Return m2.
AtomEscape :: k GroupName
  1. Let matchingGroupSpecifiers be GroupSpecifiersThatMatch(GroupName).
  2. Let parenIndices be a new empty List.
  3. For each GroupSpecifier groupSpecifier of matchingGroupSpecifiers, do
    1. Let parenIndex be CountLeftCapturingParensBefore(groupSpecifier).
    2. Append parenIndex to parenIndices.
  4. Return BackreferenceMatcher(rer, parenIndices, direction).

22.2.2.7.1 CharacterSetMatcher ( rer, A, invert, direction )

The abstract operation CharacterSetMatcher takes arguments rer (a RegExp Record), A (a CharSet), invert (a Boolean), and direction (forward or backward) and returns a Matcher. It performs the following steps when called:

  1. If rer.[[UnicodeSets]] is true, then
    1. Assert: invert is false.
    2. Assert: Every CharSetElement of A consists of a single character.
  2. Return a new Matcher with parameters (x, c) that captures rer, A, invert, and direction and performs the following steps when called:
    1. Assert: x is a MatchState.
    2. Assert: c is a MatcherContinuation.
    3. Let Input be x.[[Input]].
    4. Let e be x.[[EndIndex]].
    5. If direction is forward, let f be e + 1.
    6. Else, let f be e - 1.
    7. Let InputLength be the number of elements in Input.
    8. If f < 0 or f > InputLength, return failure.
    9. Let index be min(e, f).
    10. Let ch be the character Input[index].
    11. Let cc be Canonicalize(rer, ch).
    12. If there exists a CharSetElement in A containing exactly one character a such that Canonicalize(rer, a) is cc, let found be true; otherwise let found be false.
    13. If invert is false and found is false, return failure.
    14. If invert is true and found is true, return failure.
    15. Let cap be x.[[Captures]].
    16. Let y be the MatchState { [[Input]]: Input, [[EndIndex]]: f, [[Captures]]: cap }.
    17. Return c(y).

22.2.2.7.2 BackreferenceMatcher ( rer, ns, direction )

The abstract operation BackreferenceMatcher takes arguments rer (a RegExp Record), ns (a List of positive integers), and direction (forward or backward) and returns a Matcher. It performs the following steps when called:

  1. Return a new Matcher with parameters (x, c) that captures rer, ns, and direction and performs the following steps when called:
    1. Assert: x is a MatchState.
    2. Assert: c is a MatcherContinuation.
    3. Let Input be x.[[Input]].
    4. Let cap be x.[[Captures]].
    5. Let r be undefined.
    6. For each integer n of ns, do
      1. If cap[n] is not undefined, then
        1. Assert: r is undefined.
        2. Set r to cap[n].
    7. If r is undefined, return c(x).
    8. Let e be x.[[EndIndex]].
    9. Let rs be r.[[StartIndex]].
    10. Let re be r.[[EndIndex]].
    11. Let len be re - rs.
    12. If direction is forward, let f be e + len.
    13. Else, let f be e - len.
    14. Let InputLength be the number of elements in Input.
    15. If f < 0 or f > InputLength, return failure.
    16. Let g be min(e, f).
    17. If there exists an integer i in the interval from 0 (inclusive) to len (exclusive) such that Canonicalize(rer, Input[rs + i]) is not Canonicalize(rer, Input[g + i]), return failure.
    18. Let y be the MatchState { [[Input]]: Input, [[EndIndex]]: f, [[Captures]]: cap }.
    19. Return c(y).

22.2.2.7.3 Canonicalize ( rer, ch )

The abstract operation Canonicalize takes arguments rer (a RegExp Record) and ch (a character) and returns a character. It performs the following steps when called:

  1. If HasEitherUnicodeFlag(rer) is true and rer.[[IgnoreCase]] is true, then
    1. If the file CaseFolding.txt of the Unicode Character Database provides a simple or common case folding mapping for ch, return the result of applying that mapping to ch.
    2. Return ch.
  2. If rer.[[IgnoreCase]] is false, return ch.
  3. Assert: ch is a UTF-16 code unit.
  4. Let cp be the code point whose numeric value is the numeric value of ch.
  5. Let u be toUppercase(« cp »), according to the Unicode Default Case Conversion algorithm.
  6. Let uStr be CodePointsToString(u).
  7. If the length of uStr ≠ 1, return ch.
  8. Let cu be uStr's single code unit element.
  9. If the numeric value of ch ≥ 128 and the numeric value of cu < 128, return ch.
  10. Return cu.
Note

In case-insignificant matches when HasEitherUnicodeFlag(rer) is true, all characters are implicitly case-folded using the simple mapping provided by the Unicode Standard immediately before they are compared. The simple mapping always maps to a single code point, so it does not map, for example, ß (U+00DF LATIN SMALL LETTER SHARP S) to ss or SS. It may however map code points outside the Basic Latin block to code points within it—for example, ſ (U+017F LATIN SMALL LETTER LONG S) case-folds to s (U+0073 LATIN SMALL LETTER S) and (U+212A KELVIN SIGN) case-folds to k (U+006B LATIN SMALL LETTER K). Strings containing those code points are matched by regular expressions such as /[a-z]/ui.

In case-insignificant matches when HasEitherUnicodeFlag(rer) is false, the mapping is based on Unicode Default Case Conversion algorithm toUppercase rather than toCasefold, which results in some subtle differences. For example, (U+2126 OHM SIGN) is mapped by toUppercase to itself but by toCasefold to ω (U+03C9 GREEK SMALL LETTER OMEGA) along with Ω (U+03A9 GREEK CAPITAL LETTER OMEGA), so "\u2126" is matched by /[ω]/ui and /[\u03A9]/ui but not by /[ω]/i or /[\u03A9]/i. Also, no code point outside the Basic Latin block is mapped to a code point within it, so strings such as "\u017F ſ" and "\u212A K" are not matched by /[a-z]/i.

22.2.2.7.4 UpdateModifiers ( rer, add, remove )

The abstract operation UpdateModifiers takes arguments rer (a RegExp Record), add (a String), and remove (a String) and returns a RegExp Record. It performs the following steps when called:

  1. Assert: add and remove have no elements in common.
  2. Let ignoreCase be rer.[[IgnoreCase]].
  3. Let multiline be rer.[[Multiline]].
  4. Let dotAll be rer.[[DotAll]].
  5. Let unicode be rer.[[Unicode]].
  6. Let unicodeSets be rer.[[UnicodeSets]].
  7. Let capturingGroupsCount be rer.[[CapturingGroupsCount]].
  8. If remove contains "i", set ignoreCase to false.
  9. Else if add contains "i", set ignoreCase to true.
  10. If remove contains "m", set multiline to false.
  11. Else if add contains "m", set multiline to true.
  12. If remove contains "s", set dotAll to false.
  13. Else if add contains "s", set dotAll to true.
  14. Return the RegExp Record { [[IgnoreCase]]: ignoreCase, [[Multiline]]: multiline, [[DotAll]]: dotAll, [[Unicode]]: unicode, [[UnicodeSets]]: unicodeSets, [[CapturingGroupsCount]]: capturingGroupsCount }.

22.2.2.8 Runtime Semantics: CompileCharacterClass

The syntax-directed operation CompileCharacterClass takes argument rer (a RegExp Record) and returns a Record with fields [[CharSet]] (a CharSet) and [[Invert]] (a Boolean). It is defined piecewise over the following productions:

CharacterClass :: [ ClassContents ]
  1. Let A be CompileToCharSet of ClassContents with argument rer.
  2. Return the Record { [[CharSet]]: A, [[Invert]]: false }.
CharacterClass :: [^ ClassContents ]
  1. Let A be CompileToCharSet of ClassContents with argument rer.
  2. If rer.[[UnicodeSets]] is true, then
    1. Return the Record { [[CharSet]]: CharacterComplement(rer, A), [[Invert]]: false }.
  3. Return the Record { [[CharSet]]: A, [[Invert]]: true }.

22.2.2.9 Runtime Semantics: CompileToCharSet

The syntax-directed operation CompileToCharSet takes argument rer (a RegExp Record) and returns a CharSet.

Note 1

This section is amended in B.1.2.8.

It is defined piecewise over the following productions:

ClassContents :: [empty]
  1. Return the empty CharSet.
NonemptyClassRanges :: ClassAtom NonemptyClassRangesNoDash
  1. Let A be CompileToCharSet of ClassAtom with argument rer.
  2. Let B be CompileToCharSet of NonemptyClassRangesNoDash with argument rer.
  3. Return the union of CharSets A and B.
NonemptyClassRanges :: ClassAtom - ClassAtom ClassContents
  1. Let A be CompileToCharSet of the first ClassAtom with argument rer.
  2. Let B be CompileToCharSet of the second ClassAtom with argument rer.
  3. Let C be CompileToCharSet of ClassContents with argument rer.
  4. Let D be CharacterRange(A, B).
  5. Return the union of D and C.
NonemptyClassRangesNoDash :: ClassAtomNoDash NonemptyClassRangesNoDash
  1. Let A be CompileToCharSet of ClassAtomNoDash with argument rer.
  2. Let B be CompileToCharSet of NonemptyClassRangesNoDash with argument rer.
  3. Return the union of CharSets A and B.
NonemptyClassRangesNoDash :: ClassAtomNoDash - ClassAtom ClassContents
  1. Let A be CompileToCharSet of ClassAtomNoDash with argument rer.
  2. Let B be CompileToCharSet of ClassAtom with argument rer.
  3. Let C be CompileToCharSet of ClassContents with argument rer.
  4. Let D be CharacterRange(A, B).
  5. Return the union of D and C.
Note 2

ClassContents can expand into a single ClassAtom and/or ranges of two ClassAtom separated by dashes. In the latter case the ClassContents includes all characters between the first ClassAtom and the second ClassAtom, inclusive; an error occurs if either ClassAtom does not represent a single character (for example, if one is \w) or if the first ClassAtom's character value is strictly greater than the second ClassAtom's character value.

Note 3

Even if the pattern ignores case, the case of the two ends of a range is significant in determining which characters belong to the range. Thus, for example, the pattern /[E-F]/i matches only the letters E, F, e, and f, while the pattern /[E-f]/i matches all uppercase and lowercase letters in the Unicode Basic Latin block as well as the symbols [, \, ], ^, _, and `.

Note 4

A - character can be treated literally or it can denote a range. It is treated literally if it is the first or last character of ClassContents, the beginning or end limit of a range specification, or immediately follows a range specification.

ClassAtom :: -
  1. Return the CharSet containing the single character - U+002D (HYPHEN-MINUS).
ClassAtomNoDash :: SourceCharacter but not one of \ or ] or -
  1. Return the CharSet containing the character matched by SourceCharacter.
ClassEscape :: b - CharacterEscape
  1. Let cv be the CharacterValue of this ClassEscape.
  2. Let c be the character whose character value is cv.
  3. Return the CharSet containing the single character c.
Note 5

A ClassAtom can use any of the escape sequences that are allowed in the rest of the regular expression except for \b, \B, and backreferences. Inside a CharacterClass, \b means the backspace character, while \B and backreferences raise errors. Using a backreference inside a ClassAtom causes an error.

CharacterClassEscape :: d
  1. Return the ten-element CharSet containing the characters 0, 1, 2, 3, 4, 5, 6, 7, 8, and 9.
CharacterClassEscape :: D
  1. Let S be the CharSet returned by CharacterClassEscape :: d .
  2. Return CharacterComplement(rer, S).
CharacterClassEscape :: s
  1. Return the CharSet containing all characters corresponding to a code point on the right-hand side of the WhiteSpace or LineTerminator productions.
CharacterClassEscape :: S
  1. Let S be the CharSet returned by CharacterClassEscape :: s .
  2. Return CharacterComplement(rer, S).
CharacterClassEscape :: w
  1. Return MaybeSimpleCaseFolding(rer, WordCharacters(rer)).
CharacterClassEscape :: W
  1. Let S be the CharSet returned by CharacterClassEscape :: w .
  2. Return CharacterComplement(rer, S).
CharacterClassEscape :: p{ UnicodePropertyValueExpression }
  1. Return CompileToCharSet of UnicodePropertyValueExpression with argument rer.
CharacterClassEscape :: P{ UnicodePropertyValueExpression }
  1. Let S be CompileToCharSet of UnicodePropertyValueExpression with argument rer.
  2. Assert: S contains only single code points.
  3. Return CharacterComplement(rer, S).
UnicodePropertyValueExpression :: UnicodePropertyName = UnicodePropertyValue
  1. Let ps be the source text matched by UnicodePropertyName.
  2. Let p be UnicodeMatchProperty(rer, ps).
  3. Assert: p is a Unicode property name or property alias listed in the “Property name and aliases” column of Table 69.
  4. Let vs be the source text matched by UnicodePropertyValue.
  5. Let v be UnicodeMatchPropertyValue(p, vs).
  6. Let A be the CharSet containing all Unicode code points whose character database definition includes the property p with value v.
  7. Return MaybeSimpleCaseFolding(rer, A).
UnicodePropertyValueExpression :: LoneUnicodePropertyNameOrValue
  1. Let s be the source text matched by LoneUnicodePropertyNameOrValue.
  2. If UnicodeMatchPropertyValue(General_Category, s) is a Unicode property value or property value alias for the General_Category (gc) property listed in PropertyValueAliases.txt, then
    1. Return the CharSet containing all Unicode code points whose character database definition includes the property “General_Category” with value s.
  3. Let p be UnicodeMatchProperty(rer, s).
  4. Assert: p is a binary Unicode property or binary property alias listed in the “Property name and aliases” column of Table 70, or a binary Unicode property of strings listed in the “Property name” column of Table 71.
  5. Let A be the CharSet containing all CharSetElements whose character database definition includes the property p with value “True”.
  6. Return MaybeSimpleCaseFolding(rer, A).
ClassUnion :: ClassSetRange ClassUnionopt
  1. Let A be CompileToCharSet of ClassSetRange with argument rer.
  2. If ClassUnion is present, then
    1. Let B be CompileToCharSet of ClassUnion with argument rer.
    2. Return the union of CharSets A and B.
  3. Return A.
ClassUnion :: ClassSetOperand ClassUnionopt
  1. Let A be CompileToCharSet of ClassSetOperand with argument rer.
  2. If ClassUnion is present, then
    1. Let B be CompileToCharSet of ClassUnion with argument rer.
    2. Return the union of CharSets A and B.
  3. Return A.
ClassIntersection :: ClassSetOperand && ClassSetOperand
  1. Let A be CompileToCharSet of the first ClassSetOperand with argument rer.
  2. Let B be CompileToCharSet of the second ClassSetOperand with argument rer.
  3. Return the intersection of CharSets A and B.
ClassIntersection :: ClassIntersection && ClassSetOperand
  1. Let A be CompileToCharSet of the ClassIntersection with argument rer.
  2. Let B be CompileToCharSet of the ClassSetOperand with argument rer.
  3. Return the intersection of CharSets A and B.
ClassSubtraction :: ClassSetOperand -- ClassSetOperand
  1. Let A be CompileToCharSet of the first ClassSetOperand with argument rer.
  2. Let B be CompileToCharSet of the second ClassSetOperand with argument rer.
  3. Return the CharSet containing the CharSetElements of A which are not also CharSetElements of B.
ClassSubtraction :: ClassSubtraction -- ClassSetOperand
  1. Let A be CompileToCharSet of the ClassSubtraction with argument rer.
  2. Let B be CompileToCharSet of the ClassSetOperand with argument rer.
  3. Return the CharSet containing the CharSetElements of A which are not also CharSetElements of B.
ClassSetRange :: ClassSetCharacter - ClassSetCharacter
  1. Let A be CompileToCharSet of the first ClassSetCharacter with argument rer.
  2. Let B be CompileToCharSet of the second ClassSetCharacter with argument rer.
  3. Return MaybeSimpleCaseFolding(rer, CharacterRange(A, B)).
Note 6

The result will often consist of two or more ranges. When UnicodeSets is true and IgnoreCase is true, then MaybeSimpleCaseFolding(rer, [Ā-č]) will include only the odd-numbered code points of that range.

ClassSetOperand :: ClassSetCharacter
  1. Let A be CompileToCharSet of ClassSetCharacter with argument rer.
  2. Return MaybeSimpleCaseFolding(rer, A).
ClassSetOperand :: ClassStringDisjunction
  1. Let A be CompileToCharSet of ClassStringDisjunction with argument rer.
  2. Return MaybeSimpleCaseFolding(rer, A).
ClassSetOperand :: NestedClass
  1. Return CompileToCharSet of NestedClass with argument rer.
NestedClass :: [ ClassContents ]
  1. Return CompileToCharSet of ClassContents with argument rer.
NestedClass :: [^ ClassContents ]
  1. Let A be CompileToCharSet of ClassContents with argument rer.
  2. Return CharacterComplement(rer, A).
NestedClass :: \ CharacterClassEscape
  1. Return CompileToCharSet of CharacterClassEscape with argument rer.
ClassStringDisjunction :: \q{ ClassStringDisjunctionContents }
  1. Return CompileToCharSet of ClassStringDisjunctionContents with argument rer.
ClassStringDisjunctionContents :: ClassString
  1. Let s be CompileClassSetString of ClassString with argument rer.
  2. Return the CharSet containing the one string s.
ClassStringDisjunctionContents :: ClassString | ClassStringDisjunctionContents
  1. Let s be CompileClassSetString of ClassString with argument rer.
  2. Let A be the CharSet containing the one string s.
  3. Let B be CompileToCharSet of ClassStringDisjunctionContents with argument rer.
  4. Return the union of CharSets A and B.
ClassSetCharacter :: SourceCharacter but not ClassSetSyntaxCharacter \ CharacterEscape \ ClassSetReservedPunctuator
  1. Let cv be the CharacterValue of this ClassSetCharacter.
  2. Let c be the character whose character value is cv.
  3. Return the CharSet containing the single character c.
ClassSetCharacter :: \b
  1. Return the CharSet containing the single character U+0008 (BACKSPACE).

22.2.2.9.1 CharacterRange ( A, B )

The abstract operation CharacterRange takes arguments A (a CharSet) and B (a CharSet) and returns a CharSet. It performs the following steps when called:

  1. Assert: A and B each contain exactly one character.
  2. Let a be the one character in CharSet A.
  3. Let b be the one character in CharSet B.
  4. Let i be the character value of character a.
  5. Let j be the character value of character b.
  6. Assert: ij.
  7. Return the CharSet containing all characters with a character value in the inclusive interval from i to j.

22.2.2.9.2 HasEitherUnicodeFlag ( rer )

The abstract operation HasEitherUnicodeFlag takes argument rer (a RegExp Record) and returns a Boolean. It performs the following steps when called:

  1. If rer.[[Unicode]] is true or rer.[[UnicodeSets]] is true, then
    1. Return true.
  2. Return false.

22.2.2.9.3 WordCharacters ( rer )

The abstract operation WordCharacters takes argument rer (a RegExp Record) and returns a CharSet. Returns a CharSet containing the characters considered "word characters" for the purposes of \b, \B, \w, and \W It performs the following steps when called:

  1. Let basicWordChars be the CharSet containing every character in the ASCII word characters.
  2. Let extraWordChars be the CharSet containing all characters c such that c is not in basicWordChars but Canonicalize(rer, c) is in basicWordChars.
  3. Assert: extraWordChars is empty unless HasEitherUnicodeFlag(rer) is true and rer.[[IgnoreCase]] is true.
  4. Return the union of basicWordChars and extraWordChars.

22.2.2.9.4 AllCharacters ( rer )

The abstract operation AllCharacters takes argument rer (a RegExp Record) and returns a CharSet. Returns the set of “all characters” according to the regular expression flags. It performs the following steps when called:

  1. If rer.[[UnicodeSets]] is true and rer.[[IgnoreCase]] is true, then
    1. Return the CharSet containing all Unicode code points c that do not have a Simple Case Folding mapping (that is, scf(c)=c).
  2. Else if HasEitherUnicodeFlag(rer) is true, then
    1. Return the CharSet containing all code point values.
  3. Else,
    1. Return the CharSet containing all code unit values.

22.2.2.9.5 MaybeSimpleCaseFolding ( rer, A )

The abstract operation MaybeSimpleCaseFolding takes arguments rer (a RegExp Record) and A (a CharSet) and returns a CharSet. If rer.[[UnicodeSets]] is false or rer.[[IgnoreCase]] is false, it returns A. Otherwise, it uses the Simple Case Folding (scf(cp)) definitions in the file CaseFolding.txt of the Unicode Character Database (each of which maps a single code point to another single code point) to map each CharSetElement of A character-by-character into a canonical form and returns the resulting CharSet. It performs the following steps when called:

  1. If rer.[[UnicodeSets]] is false or rer.[[IgnoreCase]] is false, return A.
  2. Let B be a new empty CharSet.
  3. For each CharSetElement s of A, do
    1. Let t be an empty sequence of characters.
    2. For each single code point cp in s, do
      1. Append scf(cp) to t.
    3. Add t to B.
  4. Return B.

22.2.2.9.6 CharacterComplement ( rer, S )

The abstract operation CharacterComplement takes arguments rer (a RegExp Record) and S (a CharSet) and returns a CharSet. It performs the following steps when called:

  1. Let A be AllCharacters(rer).
  2. Return the CharSet containing the CharSetElements of A which are not also CharSetElements of S.

22.2.2.9.7 UnicodeMatchProperty ( rer, p )

The abstract operation UnicodeMatchProperty takes arguments rer (a RegExp Record) and p (ECMAScript source text) and returns a Unicode property name. It performs the following steps when called:

  1. If rer.[[UnicodeSets]] is true and p is a Unicode property name listed in the “Property name” column of Table 71, then
    1. Return the List of Unicode code points p.
  2. Assert: p is a Unicode property name or property alias listed in the “Property name and aliases” column of Table 69 or Table 70.
  3. Let c be the canonical property name of p as given in the “Canonical property name” column of the corresponding row.
  4. Return the List of Unicode code points c.

Implementations must support the Unicode property names and aliases listed in Table 69, Table 70, and Table 71. To ensure interoperability, implementations must not support any other property names or aliases.

Note 1

For example, Script_Extensions (property name) and scx (property alias) are valid, but script_extensions or Scx aren't.

Note 2

The listed properties form a superset of what UTS18 RL1.2 requires.

Note 3

The spellings of entries in these tables (including casing) match the spellings used in the file PropertyAliases.txt in the Unicode Character Database. The precise spellings in that file are guaranteed to be stable.

Table 69: Non-binary Unicode property aliases and their canonical property names
Property name and aliases Canonical property name
General_Category General_Category
gc
Script Script
sc
Script_Extensions Script_Extensions
scx
Table 70: Binary Unicode property aliases and their canonical property names
Property name and aliases Canonical property name
ASCII ASCII
ASCII_Hex_Digit ASCII_Hex_Digit
AHex
Alphabetic Alphabetic
Alpha
Any Any
Assigned Assigned
Bidi_Control Bidi_Control
Bidi_C
Bidi_Mirrored Bidi_Mirrored
Bidi_M
Case_Ignorable Case_Ignorable
CI
Cased Cased
Changes_When_Casefolded Changes_When_Casefolded
CWCF
Changes_When_Casemapped Changes_When_Casemapped
CWCM
Changes_When_Lowercased Changes_When_Lowercased
CWL
Changes_When_NFKC_Casefolded Changes_When_NFKC_Casefolded
CWKCF
Changes_When_Titlecased Changes_When_Titlecased
CWT
Changes_When_Uppercased Changes_When_Uppercased
CWU
Dash Dash
Default_Ignorable_Code_Point Default_Ignorable_Code_Point
DI
Deprecated Deprecated
Dep
Diacritic Diacritic
Dia
Emoji Emoji
Emoji_Component Emoji_Component
EComp
Emoji_Modifier Emoji_Modifier
EMod
Emoji_Modifier_Base Emoji_Modifier_Base
EBase
Emoji_Presentation Emoji_Presentation
EPres
Extended_Pictographic Extended_Pictographic
ExtPict
Extender Extender
Ext
Grapheme_Base Grapheme_Base
Gr_Base
Grapheme_Extend Grapheme_Extend
Gr_Ext
Hex_Digit Hex_Digit
Hex
IDS_Binary_Operator IDS_Binary_Operator
IDSB
IDS_Trinary_Operator IDS_Trinary_Operator
IDST
ID_Continue ID_Continue
IDC
ID_Start ID_Start
IDS
Ideographic Ideographic
Ideo
Join_Control Join_Control
Join_C
Logical_Order_Exception Logical_Order_Exception
LOE
Lowercase Lowercase
Lower
Math Math
Noncharacter_Code_Point Noncharacter_Code_Point
NChar
Pattern_Syntax Pattern_Syntax
Pat_Syn
Pattern_White_Space Pattern_White_Space
Pat_WS
Quotation_Mark Quotation_Mark
QMark
Radical Radical
Regional_Indicator Regional_Indicator
RI
Sentence_Terminal Sentence_Terminal
STerm
Soft_Dotted Soft_Dotted
SD
Terminal_Punctuation Terminal_Punctuation
Term
Unified_Ideograph Unified_Ideograph
UIdeo
Uppercase Uppercase
Upper
Variation_Selector Variation_Selector
VS
White_Space White_Space
space
XID_Continue XID_Continue
XIDC
XID_Start XID_Start
XIDS
Table 71: Binary Unicode properties of strings
Property name
Basic_Emoji
Emoji_Keycap_Sequence
RGI_Emoji_Modifier_Sequence
RGI_Emoji_Flag_Sequence
RGI_Emoji_Tag_Sequence
RGI_Emoji_ZWJ_Sequence
RGI_Emoji

22.2.2.9.8 UnicodeMatchPropertyValue ( p, v )

The abstract operation UnicodeMatchPropertyValue takes arguments p (ECMAScript source text) and v (ECMAScript source text) and returns a Unicode property value. It performs the following steps when called:

  1. Assert: p is a canonical, unaliased Unicode property name listed in the “Canonical property name” column of Table 69.
  2. Assert: v is a property value or property value alias for the Unicode property p listed in PropertyValueAliases.txt.
  3. Let value be the canonical property value of v as given in the “Canonical property value” column of the corresponding row.
  4. Return the List of Unicode code points value.

Implementations must support the Unicode property values and property value aliases listed in PropertyValueAliases.txt for the properties listed in Table 69. To ensure interoperability, implementations must not support any other property values or property value aliases.

Note 1

For example, Xpeo and Old_Persian are valid Script_Extensions values, but xpeo and Old Persian aren't.

Note 2

This algorithm differs from the matching rules for symbolic values listed in UAX44: case, white space, U+002D (HYPHEN-MINUS), and U+005F (LOW LINE) are not ignored, and the Is prefix is not supported.

22.2.2.10 Runtime Semantics: CompileClassSetString

The syntax-directed operation CompileClassSetString takes argument rer (a RegExp Record) and returns a sequence of characters. It is defined piecewise over the following productions:

ClassString :: [empty]
  1. Return an empty sequence of characters.
ClassString :: NonEmptyClassString
  1. Return CompileClassSetString of NonEmptyClassString with argument rer.
NonEmptyClassString :: ClassSetCharacter NonEmptyClassStringopt
  1. Let cs be CompileToCharSet of ClassSetCharacter with argument rer.
  2. Let s1 be the sequence of characters that is the single CharSetElement of cs.
  3. If NonEmptyClassString is present, then
    1. Let s2 be CompileClassSetString of NonEmptyClassString with argument rer.
    2. Return the concatenation of s1 and s2.
  4. Return s1.

22.2.3 Abstract Operations for RegExp Creation

22.2.3.1 RegExpCreate ( P, F )

The abstract operation RegExpCreate takes arguments P (an ECMAScript language value) and F (a String or undefined) and returns either a normal completion containing an Object or a throw completion. It performs the following steps when called:

  1. Let obj be ! RegExpAlloc(%RegExp%).
  2. Return ? RegExpInitialize(obj, P, F).

22.2.3.2 RegExpAlloc ( newTarget )

The abstract operation RegExpAlloc takes argument newTarget (a constructor) and returns either a normal completion containing an Object or a throw completion. It performs the following steps when called:

  1. Let obj be ? OrdinaryCreateFromConstructor(newTarget, "%RegExp.prototype%", « [[OriginalSource]], [[OriginalFlags]], [[RegExpRecord]], [[RegExpMatcher]] »).
  2. Perform ! DefinePropertyOrThrow(obj, "lastIndex", PropertyDescriptor { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }).
  3. Return obj.

22.2.3.3 RegExpInitialize ( obj, pattern, flags )

The abstract operation RegExpInitialize takes arguments obj (an Object), pattern (an ECMAScript language value), and flags (an ECMAScript language value) and returns either a normal completion containing an Object or a throw completion. It performs the following steps when called:

  1. If pattern is undefined, let P be the empty String.
  2. Else, let P be ? ToString(pattern).
  3. If flags is undefined, let F be the empty String.
  4. Else, let F be ? ToString(flags).
  5. If F contains any code unit other than "d", "g", "i", "m", "s", "u", "v", or "y", or if F contains any code unit more than once, throw a SyntaxError exception.
  6. If F contains "i", let i be true; else let i be false.
  7. If F contains "m", let m be true; else let m be false.
  8. If F contains "s", let s be true; else let s be false.
  9. If F contains "u", let u be true; else let u be false.
  10. If F contains "v", let v be true; else let v be false.
  11. If u is true or v is true, then
    1. Let patternText be StringToCodePoints(P).
  12. Else,
    1. Let patternText be the result of interpreting each of P's 16-bit elements as a Unicode BMP code point. UTF-16 decoding is not applied to the elements.
  13. Let parseResult be ParsePattern(patternText, u, v).
  14. If parseResult is a non-empty List of SyntaxError objects, throw a SyntaxError exception.
  15. Assert: parseResult is a Pattern Parse Node.
  16. Set obj.[[OriginalSource]] to P.
  17. Set obj.[[OriginalFlags]] to F.
  18. Let capturingGroupsCount be CountLeftCapturingParensWithin(parseResult).
  19. Let rer be the RegExp Record { [[IgnoreCase]]: i, [[Multiline]]: m, [[DotAll]]: s, [[Unicode]]: u, [[UnicodeSets]]: v, [[CapturingGroupsCount]]: capturingGroupsCount }.
  20. Set obj.[[RegExpRecord]] to rer.
  21. Set obj.[[RegExpMatcher]] to CompilePattern of parseResult with argument rer.
  22. Perform ? Set(obj, "lastIndex", +0𝔽, true).
  23. Return obj.

22.2.3.4 Static Semantics: ParsePattern ( patternText, u, v )

The abstract operation ParsePattern takes arguments patternText (a sequence of Unicode code points), u (a Boolean), and v (a Boolean) and returns a Parse Node or a non-empty List of SyntaxError objects.

Note

This section is amended in B.1.2.9.

It performs the following steps when called:

  1. If v is true and u is true, then
    1. Let parseResult be a List containing one or more SyntaxError objects.
  2. Else if v is true, then
    1. Let parseResult be ParseText(patternText, Pattern[+UnicodeMode, +UnicodeSetsMode, +NamedCaptureGroups]).
  3. Else if u is true, then
    1. Let parseResult be ParseText(patternText, Pattern[+UnicodeMode, ~UnicodeSetsMode, +NamedCaptureGroups]).
  4. Else,
    1. Let parseResult be ParseText(patternText, Pattern[~UnicodeMode, ~UnicodeSetsMode, +NamedCaptureGroups]).
  5. Return parseResult.

22.2.4 The RegExp Constructor

The RegExp constructor:

  • is %RegExp%.
  • is the initial value of the "RegExp" property of the global object.
  • creates and initializes a new RegExp object when called as a constructor.
  • when called as a function rather than as a constructor, returns either a new RegExp object, or the argument itself if the only argument is a RegExp object.
  • may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified RegExp behaviour must include a super call to the RegExp constructor to create and initialize subclass instances with the necessary internal slots.

22.2.4.1 RegExp ( pattern, flags )

This function performs the following steps when called:

  1. Let patternIsRegExp be ? IsRegExp(pattern).
  2. If NewTarget is undefined, then
    1. Let newTarget be the active function object.
    2. If patternIsRegExp is true and flags is undefined, then
      1. Let patternConstructor be ? Get(pattern, "constructor").
      2. If SameValue(newTarget, patternConstructor) is true, return pattern.
  3. Else,
    1. Let newTarget be NewTarget.
  4. If pattern is an Object and pattern has a [[RegExpMatcher]] internal slot, then
    1. Let P be pattern.[[OriginalSource]].
    2. If flags is undefined, let F be pattern.[[OriginalFlags]].
    3. Else, let F be flags.
  5. Else if patternIsRegExp is true, then
    1. Let P be ? Get(pattern, "source").
    2. If flags is undefined, then
      1. Let F be ? Get(pattern, "flags").
    3. Else,
      1. Let F be flags.
  6. Else,
    1. Let P be pattern.
    2. Let F be flags.
  7. Let O be ? RegExpAlloc(newTarget).
  8. Return ? RegExpInitialize(O, P, F).
Note

If pattern is supplied using a StringLiteral, the usual escape sequence substitutions are performed before the String is processed by this function. If pattern must contain an escape sequence to be recognized by this function, any U+005C (REVERSE SOLIDUS) code points must be escaped within the StringLiteral to prevent them being removed when the contents of the StringLiteral are formed.

22.2.5 Properties of the RegExp Constructor

The RegExp constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

22.2.5.1 RegExp.escape ( S )

This function returns a copy of S in which characters that are potentially special in a regular expression Pattern have been replaced by equivalent escape sequences.

It performs the following steps when called:

  1. If S is not a String, throw a TypeError exception.
  2. Let escaped be the empty String.
  3. Let cpList be StringToCodePoints(S).
  4. For each code point cp of cpList, do
    1. If escaped is the empty String and cp is matched by either DecimalDigit or AsciiLetter, then
      1. NOTE: Escaping a leading digit ensures that output corresponds with pattern text which may be used after a \0 character escape or a DecimalEscape such as \1 and still match S rather than be interpreted as an extension of the preceding escape sequence. Escaping a leading ASCII letter does the same for the context after \c.
      2. Let numericValue be the numeric value of cp.
      3. Let hex be Number::toString(𝔽(numericValue), 16).
      4. Assert: The length of hex is 2.
      5. Set escaped to the string-concatenation of the code unit 0x005C (REVERSE SOLIDUS), "x", and hex.
    2. Else,
      1. Set escaped to the string-concatenation of escaped and EncodeForRegExpEscape(cp).
  5. Return escaped.
Note

Despite having similar names, EscapeRegExpPattern and RegExp.escape do not perform similar actions. The former escapes a pattern for representation as a string, while this function escapes a string for representation inside a pattern.

22.2.5.1.1 EncodeForRegExpEscape ( cp )

The abstract operation EncodeForRegExpEscape takes argument cp (a code point) and returns a String. It returns a String representing a Pattern for matching cp. If cp is white space or an ASCII punctuator, the returned value is an escape sequence. Otherwise, the returned value is a String representation of cp itself. It performs the following steps when called:

  1. If cp is matched by SyntaxCharacter or cp is U+002F (SOLIDUS), then
    1. Return the string-concatenation of 0x005C (REVERSE SOLIDUS) and UTF16EncodeCodePoint(cp).
  2. Else if cp is a code point listed in the “Code Point” column of Table 67, then
    1. Return the string-concatenation of 0x005C (REVERSE SOLIDUS) and the string in the “ControlEscape” column of the row whose “Code Point” column contains cp.
  3. Let otherPunctuators be the string-concatenation of ",-=<>#&!%:;@~'`" and the code unit 0x0022 (QUOTATION MARK).
  4. Let toEscape be StringToCodePoints(otherPunctuators).
  5. If toEscape contains cp, cp is matched by either WhiteSpace or LineTerminator, or cp has the same numeric value as a leading surrogate or trailing surrogate, then
    1. Let cpNum be the numeric value of cp.
    2. If cpNum ≤ 0xFF, then
      1. Let hex be Number::toString(𝔽(cpNum), 16).
      2. Return the string-concatenation of the code unit 0x005C (REVERSE SOLIDUS), "x", and StringPad(hex, 2, "0", start).
    3. Let escaped be the empty String.
    4. Let codeUnits be UTF16EncodeCodePoint(cp).
    5. For each code unit cu of codeUnits, do
      1. Set escaped to the string-concatenation of escaped and UnicodeEscape(cu).
    6. Return escaped.
  6. Return UTF16EncodeCodePoint(cp).

22.2.5.2 RegExp.prototype

The initial value of RegExp.prototype is the RegExp prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

22.2.5.3 get RegExp [ %Symbol.species% ]

RegExp[%Symbol.species%] is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Return the this value.

The value of the "name" property of this function is "get [Symbol.species]".

Note

RegExp prototype methods normally use their this value's constructor to create a derived object. However, a subclass constructor may over-ride that default behaviour by redefining its %Symbol.species% property.

22.2.6 Properties of the RegExp Prototype Object

The RegExp prototype object:

  • is %RegExp.prototype%.
  • is an ordinary object.
  • is not a RegExp instance and does not have a [[RegExpMatcher]] internal slot or any of the other internal slots of RegExp instance objects.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.
Note

The RegExp prototype object does not have a "valueOf" property of its own; however, it inherits the "valueOf" property from the Object prototype object.

22.2.6.1 RegExp.prototype.constructor

The initial value of RegExp.prototype.constructor is %RegExp%.

22.2.6.2 RegExp.prototype.exec ( string )

This method searches string for an occurrence of the regular expression pattern and returns an Array containing the results of the match, or null if string did not match.

It performs the following steps when called:

  1. Let R be the this value.
  2. Perform ? RequireInternalSlot(R, [[RegExpMatcher]]).
  3. Let S be ? ToString(string).
  4. Return ? RegExpBuiltinExec(R, S).

22.2.6.3 get RegExp.prototype.dotAll

RegExp.prototype.dotAll is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let R be the this value.
  2. Let cu be the code unit 0x0073 (LATIN SMALL LETTER S).
  3. Return ? RegExpHasFlag(R, cu).

22.2.6.4 get RegExp.prototype.flags

RegExp.prototype.flags is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let R be the this value.
  2. If R is not an Object, throw a TypeError exception.
  3. Let codeUnits be a new empty List.
  4. Let hasIndices be ToBoolean(? Get(R, "hasIndices")).
  5. If hasIndices is true, append the code unit 0x0064 (LATIN SMALL LETTER D) to codeUnits.
  6. Let global be ToBoolean(? Get(R, "global")).
  7. If global is true, append the code unit 0x0067 (LATIN SMALL LETTER G) to codeUnits.
  8. Let ignoreCase be ToBoolean(? Get(R, "ignoreCase")).
  9. If ignoreCase is true, append the code unit 0x0069 (LATIN SMALL LETTER I) to codeUnits.
  10. Let multiline be ToBoolean(? Get(R, "multiline")).
  11. If multiline is true, append the code unit 0x006D (LATIN SMALL LETTER M) to codeUnits.
  12. Let dotAll be ToBoolean(? Get(R, "dotAll")).
  13. If dotAll is true, append the code unit 0x0073 (LATIN SMALL LETTER S) to codeUnits.
  14. Let unicode be ToBoolean(? Get(R, "unicode")).
  15. If unicode is true, append the code unit 0x0075 (LATIN SMALL LETTER U) to codeUnits.
  16. Let unicodeSets be ToBoolean(? Get(R, "unicodeSets")).
  17. If unicodeSets is true, append the code unit 0x0076 (LATIN SMALL LETTER V) to codeUnits.
  18. Let sticky be ToBoolean(? Get(R, "sticky")).
  19. If sticky is true, append the code unit 0x0079 (LATIN SMALL LETTER Y) to codeUnits.
  20. Return the String value whose code units are the elements of the List codeUnits. If codeUnits has no elements, the empty String is returned.

22.2.6.4.1 RegExpHasFlag ( R, codeUnit )

The abstract operation RegExpHasFlag takes arguments R (an ECMAScript language value) and codeUnit (a code unit) and returns either a normal completion containing either a Boolean or undefined, or a throw completion. It performs the following steps when called:

  1. If R is not an Object, throw a TypeError exception.
  2. If R does not have an [[OriginalFlags]] internal slot, then
    1. If SameValue(R, %RegExp.prototype%) is true, return undefined.
    2. Otherwise, throw a TypeError exception.
  3. Let flags be R.[[OriginalFlags]].
  4. If flags contains codeUnit, return true.
  5. Return false.

22.2.6.5 get RegExp.prototype.global

RegExp.prototype.global is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let R be the this value.
  2. Let cu be the code unit 0x0067 (LATIN SMALL LETTER G).
  3. Return ? RegExpHasFlag(R, cu).

22.2.6.6 get RegExp.prototype.hasIndices

RegExp.prototype.hasIndices is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let R be the this value.
  2. Let cu be the code unit 0x0064 (LATIN SMALL LETTER D).
  3. Return ? RegExpHasFlag(R, cu).

22.2.6.7 get RegExp.prototype.ignoreCase

RegExp.prototype.ignoreCase is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let R be the this value.
  2. Let cu be the code unit 0x0069 (LATIN SMALL LETTER I).
  3. Return ? RegExpHasFlag(R, cu).

22.2.6.8 RegExp.prototype [ %Symbol.match% ] ( string )

This method performs the following steps when called:

  1. Let rx be the this value.
  2. If rx is not an Object, throw a TypeError exception.
  3. Let S be ? ToString(string).
  4. Let flags be ? ToString(? Get(rx, "flags")).
  5. If flags does not contain "g", then
    1. Return ? RegExpExec(rx, S).
  6. Else,
    1. If flags contains "u" or flags contains "v", let fullUnicode be true; otherwise let fullUnicode be false.
    2. Perform ? Set(rx, "lastIndex", +0𝔽, true).
    3. Let A be ! ArrayCreate(0).
    4. Let n be 0.
    5. Repeat,
      1. Let result be ? RegExpExec(rx, S).
      2. If result is null, then
        1. If n = 0, return null.
        2. Return A.
      3. Else,
        1. Let matchStr be ? ToString(? Get(result, "0")).
        2. Perform ! CreateDataPropertyOrThrow(A, ! ToString(𝔽(n)), matchStr).
        3. If matchStr is the empty String, then
          1. Let thisIndex be (? ToLength(? Get(rx, "lastIndex"))).
          2. Let nextIndex be AdvanceStringIndex(S, thisIndex, fullUnicode).
          3. Perform ? Set(rx, "lastIndex", 𝔽(nextIndex), true).
        4. Set n to n + 1.

The value of the "name" property of this method is "[Symbol.match]".

Note

The %Symbol.match% property is used by the IsRegExp abstract operation to identify objects that have the basic behaviour of regular expressions. The absence of a %Symbol.match% property or the existence of such a property whose value does not Boolean coerce to true indicates that the object is not intended to be used as a regular expression object.

22.2.6.9 RegExp.prototype [ %Symbol.matchAll% ] ( string )

This method performs the following steps when called:

  1. Let R be the this value.
  2. If R is not an Object, throw a TypeError exception.
  3. Let S be ? ToString(string).
  4. Let C be ? SpeciesConstructor(R, %RegExp%).
  5. Let flags be ? ToString(? Get(R, "flags")).
  6. Let matcher be ? Construct(C, « R, flags »).
  7. Let lastIndex be ? ToLength(? Get(R, "lastIndex")).
  8. Perform ? Set(matcher, "lastIndex", lastIndex, true).
  9. If flags contains "g", let global be true.
  10. Else, let global be false.
  11. If flags contains "u" or flags contains "v", let fullUnicode be true.
  12. Else, let fullUnicode be false.
  13. Return CreateRegExpStringIterator(matcher, S, global, fullUnicode).

The value of the "name" property of this method is "[Symbol.matchAll]".

22.2.6.10 get RegExp.prototype.multiline

RegExp.prototype.multiline is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let R be the this value.
  2. Let cu be the code unit 0x006D (LATIN SMALL LETTER M).
  3. Return ? RegExpHasFlag(R, cu).

22.2.6.11 RegExp.prototype [ %Symbol.replace% ] ( string, replaceValue )

This method performs the following steps when called:

  1. Let rx be the this value.
  2. If rx is not an Object, throw a TypeError exception.
  3. Let S be ? ToString(string).
  4. Let lengthS be the length of S.
  5. Let functionalReplace be IsCallable(replaceValue).
  6. If functionalReplace is false, then
    1. Set replaceValue to ? ToString(replaceValue).
  7. Let flags be ? ToString(? Get(rx, "flags")).
  8. If flags contains "g", let global be true; otherwise let global be false.
  9. If global is true, then
    1. Perform ? Set(rx, "lastIndex", +0𝔽, true).
  10. Let results be a new empty List.
  11. Let done be false.
  12. Repeat, while done is false,
    1. Let result be ? RegExpExec(rx, S).
    2. If result is null, then
      1. Set done to true.
    3. Else,
      1. Append result to results.
      2. If global is false, then
        1. Set done to true.
      3. Else,
        1. Let matchStr be ? ToString(? Get(result, "0")).
        2. If matchStr is the empty String, then
          1. Let thisIndex be (? ToLength(? Get(rx, "lastIndex"))).
          2. If flags contains "u" or flags contains "v", let fullUnicode be true; otherwise let fullUnicode be false.
          3. Let nextIndex be AdvanceStringIndex(S, thisIndex, fullUnicode).
          4. Perform ? Set(rx, "lastIndex", 𝔽(nextIndex), true).
  13. Let accumulatedResult be the empty String.
  14. Let nextSourcePosition be 0.
  15. For each element result of results, do
    1. Let resultLength be ? LengthOfArrayLike(result).
    2. Let nCaptures be max(resultLength - 1, 0).
    3. Let matched be ? ToString(? Get(result, "0")).
    4. Let matchLength be the length of matched.
    5. Let position be ? ToIntegerOrInfinity(? Get(result, "index")).
    6. Set position to the result of clamping position between 0 and lengthS.
    7. Let captures be a new empty List.
    8. Let n be 1.
    9. Repeat, while nnCaptures,
      1. Let capN be ? Get(result, ! ToString(𝔽(n))).
      2. If capN is not undefined, then
        1. Set capN to ? ToString(capN).
      3. Append capN to captures.
      4. NOTE: When n = 1, the preceding step puts the first element into captures (at index 0). More generally, the nth capture (the characters captured by the nth set of capturing parentheses) is at captures[n - 1].
      5. Set n to n + 1.
    10. Let namedCaptures be ? Get(result, "groups").
    11. If functionalReplace is true, then
      1. Let replacerArgs be the list-concatenation of « matched », captures, and « 𝔽(position), S ».
      2. If namedCaptures is not undefined, then
        1. Append namedCaptures to replacerArgs.
      3. Let replacementValue be ? Call(replaceValue, undefined, replacerArgs).
      4. Let replacementString be ? ToString(replacementValue).
    12. Else,
      1. If namedCaptures is not undefined, then
        1. Set namedCaptures to ? ToObject(namedCaptures).
      2. Let replacementString be ? GetSubstitution(matched, S, position, captures, namedCaptures, replaceValue).
    13. If positionnextSourcePosition, then
      1. NOTE: position should not normally move backwards. If it does, it is an indication of an ill-behaving RegExp subclass or use of an access triggered side-effect to change the global flag or other characteristics of rx. In such cases, the corresponding substitution is ignored.
      2. Set accumulatedResult to the string-concatenation of accumulatedResult, the substring of S from nextSourcePosition to position, and replacementString.
      3. Set nextSourcePosition to position + matchLength.
  16. If nextSourcePositionlengthS, return accumulatedResult.
  17. Return the string-concatenation of accumulatedResult and the substring of S from nextSourcePosition.

The value of the "name" property of this method is "[Symbol.replace]".

22.2.6.12 RegExp.prototype [ %Symbol.search% ] ( string )

This method performs the following steps when called:

  1. Let rx be the this value.
  2. If rx is not an Object, throw a TypeError exception.
  3. Let S be ? ToString(string).
  4. Let previousLastIndex be ? Get(rx, "lastIndex").
  5. If previousLastIndex is not +0𝔽, then
    1. Perform ? Set(rx, "lastIndex", +0𝔽, true).
  6. Let result be ? RegExpExec(rx, S).
  7. Let currentLastIndex be ? Get(rx, "lastIndex").
  8. If SameValue(currentLastIndex, previousLastIndex) is false, then
    1. Perform ? Set(rx, "lastIndex", previousLastIndex, true).
  9. If result is null, return -1𝔽.
  10. Return ? Get(result, "index").

The value of the "name" property of this method is "[Symbol.search]".

Note

The "lastIndex" and "global" properties of this RegExp object are ignored when performing the search. The "lastIndex" property is left unchanged.

22.2.6.13 get RegExp.prototype.source

RegExp.prototype.source is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let R be the this value.
  2. If R is not an Object, throw a TypeError exception.
  3. If R does not have an [[OriginalSource]] internal slot, then
    1. If SameValue(R, %RegExp.prototype%) is true, return "(?:)".
    2. Otherwise, throw a TypeError exception.
  4. Assert: R has an [[OriginalFlags]] internal slot.
  5. Let src be R.[[OriginalSource]].
  6. Let flags be R.[[OriginalFlags]].
  7. Return EscapeRegExpPattern(src, flags).

22.2.6.13.1 EscapeRegExpPattern ( P, F )

The abstract operation EscapeRegExpPattern takes arguments P (a String) and F (a String) and returns a String. It performs the following steps when called:

  1. If F contains "v", then
    1. Let patternSymbol be Pattern[+UnicodeMode, +UnicodeSetsMode].
  2. Else if F contains "u", then
    1. Let patternSymbol be Pattern[+UnicodeMode, ~UnicodeSetsMode].
  3. Else,
    1. Let patternSymbol be Pattern[~UnicodeMode, ~UnicodeSetsMode].
  4. Let S be a String in the form of a patternSymbol equivalent to P interpreted as UTF-16 encoded Unicode code points (6.1.4), in which certain code points are escaped as described below. S may or may not differ from P; however, the Abstract Closure that would result from evaluating S as a patternSymbol must behave identically to the Abstract Closure given by the constructed object's [[RegExpMatcher]] internal slot. Multiple calls to this abstract operation using the same values for P and F must produce identical results.
  5. The code points / or any LineTerminator occurring in the pattern shall be escaped in S as necessary to ensure that the string-concatenation of "/", S, "/", and F can be parsed (in an appropriate lexical context) as a RegularExpressionLiteral that behaves identically to the constructed regular expression. For example, if P is "/", then S could be "\/" or "\u002F", among other possibilities, but not "/", because /// followed by F would be parsed as a SingleLineComment rather than a RegularExpressionLiteral. If P is the empty String, this specification can be met by letting S be "(?:)".
  6. Return S.
Note

Despite having similar names, RegExp.escape and EscapeRegExpPattern do not perform similar actions. The former escapes a string for representation inside a pattern, while this function escapes a pattern for representation as a string.

22.2.6.14 RegExp.prototype [ %Symbol.split% ] ( string, limit )

Note 1

This method returns an Array into which substrings of the result of converting string to a String have been stored. The substrings are determined by searching from left to right for matches of the this value regular expression; these occurrences are not part of any String in the returned array, but serve to divide up the String value.

The this value may be an empty regular expression or a regular expression that can match an empty String. In this case, the regular expression does not match the empty substring at the beginning or end of the input String, nor does it match the empty substring at the end of the previous separator match. (For example, if the regular expression matches the empty String, the String is split up into individual code unit elements; the length of the result array equals the length of the String, and each substring contains one code unit.) Only the first match at a given index of the String is considered, even if backtracking could yield a non-empty substring match at that index. (For example, /a*?/[Symbol.split]("ab") evaluates to the array ["a", "b"], while /a*/[Symbol.split]("ab") evaluates to the array ["","b"].)

If string is (or converts to) the empty String, the result depends on whether the regular expression can match the empty String. If it can, the result array contains no elements. Otherwise, the result array contains one element, which is the empty String.

If the regular expression contains capturing parentheses, then each time separator is matched the results (including any undefined results) of the capturing parentheses are spliced into the output array. For example,

/<(\/)?([^<>]+)>/[Symbol.split]("A<B>bold</B>and<CODE>coded</CODE>")

evaluates to the array

["A", undefined, "B", "bold", "/", "B", "and", undefined, "CODE", "coded", "/", "CODE", ""]

If limit is not undefined, then the output array is truncated so that it contains no more than limit elements.

This method performs the following steps when called:

  1. Let rx be the this value.
  2. If rx is not an Object, throw a TypeError exception.
  3. Let S be ? ToString(string).
  4. Let C be ? SpeciesConstructor(rx, %RegExp%).
  5. Let flags be ? ToString(? Get(rx, "flags")).
  6. If flags contains "u" or flags contains "v", let unicodeMatching be true.
  7. Else, let unicodeMatching be false.
  8. If flags contains "y", let newFlags be flags.
  9. Else, let newFlags be the string-concatenation of flags and "y".
  10. Let splitter be ? Construct(C, « rx, newFlags »).
  11. Let A be ! ArrayCreate(0).
  12. Let lengthA be 0.
  13. If limit is undefined, let lim be 232 - 1; else let lim be (? ToUint32(limit)).
  14. If lim = 0, return A.
  15. If S is the empty String, then
    1. Let z be ? RegExpExec(splitter, S).
    2. If z is not null, return A.
    3. Perform ! CreateDataPropertyOrThrow(A, "0", S).
    4. Return A.
  16. Let size be the length of S.
  17. Let p be 0.
  18. Let q be p.
  19. Repeat, while q < size,
    1. Perform ? Set(splitter, "lastIndex", 𝔽(q), true).
    2. Let z be ? RegExpExec(splitter, S).
    3. If z is null, then
      1. Set q to AdvanceStringIndex(S, q, unicodeMatching).
    4. Else,
      1. Let e be (? ToLength(? Get(splitter, "lastIndex"))).
      2. Set e to min(e, size).
      3. If e = p, then
        1. Set q to AdvanceStringIndex(S, q, unicodeMatching).
      4. Else,
        1. Let T be the substring of S from p to q.
        2. Perform ! CreateDataPropertyOrThrow(A, ! ToString(𝔽(lengthA)), T).
        3. Set lengthA to lengthA + 1.
        4. If lengthA = lim, return A.
        5. Set p to e.
        6. Let numberOfCaptures be ? LengthOfArrayLike(z).
        7. Set numberOfCaptures to max(numberOfCaptures - 1, 0).
        8. Let i be 1.
        9. Repeat, while inumberOfCaptures,
          1. Let nextCapture be ? Get(z, ! ToString(𝔽(i))).
          2. Perform ! CreateDataPropertyOrThrow(A, ! ToString(𝔽(lengthA)), nextCapture).
          3. Set i to i + 1.
          4. Set lengthA to lengthA + 1.
          5. If lengthA = lim, return A.
        10. Set q to p.
  20. Let T be the substring of S from p to size.
  21. Perform ! CreateDataPropertyOrThrow(A, ! ToString(𝔽(lengthA)), T).
  22. Return A.

The value of the "name" property of this method is "[Symbol.split]".

Note 2

This method ignores the value of the "global" and "sticky" properties of this RegExp object.

22.2.6.15 get RegExp.prototype.sticky

RegExp.prototype.sticky is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let R be the this value.
  2. Let cu be the code unit 0x0079 (LATIN SMALL LETTER Y).
  3. Return ? RegExpHasFlag(R, cu).

22.2.6.16 RegExp.prototype.test ( S )

This method performs the following steps when called:

  1. Let R be the this value.
  2. If R is not an Object, throw a TypeError exception.
  3. Let string be ? ToString(S).
  4. Let match be ? RegExpExec(R, string).
  5. If match is not null, return true; else return false.

22.2.6.17 RegExp.prototype.toString ( )

  1. Let R be the this value.
  2. If R is not an Object, throw a TypeError exception.
  3. Let pattern be ? ToString(? Get(R, "source")).
  4. Let flags be ? ToString(? Get(R, "flags")).
  5. Let result be the string-concatenation of "/", pattern, "/", and flags.
  6. Return result.
Note

The returned String has the form of a RegularExpressionLiteral that evaluates to another RegExp object with the same behaviour as this object.

22.2.6.18 get RegExp.prototype.unicode

RegExp.prototype.unicode is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let R be the this value.
  2. Let cu be the code unit 0x0075 (LATIN SMALL LETTER U).
  3. Return ? RegExpHasFlag(R, cu).

22.2.6.19 get RegExp.prototype.unicodeSets

RegExp.prototype.unicodeSets is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let R be the this value.
  2. Let cu be the code unit 0x0076 (LATIN SMALL LETTER V).
  3. Return ? RegExpHasFlag(R, cu).

22.2.7 Abstract Operations for RegExp Matching

22.2.7.1 RegExpExec ( R, S )

The abstract operation RegExpExec takes arguments R (an Object) and S (a String) and returns either a normal completion containing either an Object or null, or a throw completion. It performs the following steps when called:

  1. Let exec be ? Get(R, "exec").
  2. If IsCallable(exec) is true, then
    1. Let result be ? Call(exec, R, « S »).
    2. If result is not an Object and result is not null, throw a TypeError exception.
    3. Return result.
  3. Perform ? RequireInternalSlot(R, [[RegExpMatcher]]).
  4. Return ? RegExpBuiltinExec(R, S).
Note

If a callable "exec" property is not found this algorithm falls back to attempting to use the built-in RegExp matching algorithm. This provides compatible behaviour for code written for prior editions where most built-in algorithms that use regular expressions did not perform a dynamic property lookup of "exec".

22.2.7.2 RegExpBuiltinExec ( R, S )

The abstract operation RegExpBuiltinExec takes arguments R (an initialized RegExp instance) and S (a String) and returns either a normal completion containing either an Array exotic object or null, or a throw completion. It performs the following steps when called:

  1. Let length be the length of S.
  2. Let lastIndex be (? ToLength(? Get(R, "lastIndex"))).
  3. Let flags be R.[[OriginalFlags]].
  4. If flags contains "g", let global be true; else let global be false.
  5. If flags contains "y", let sticky be true; else let sticky be false.
  6. If flags contains "d", let hasIndices be true; else let hasIndices be false.
  7. If global is false and sticky is false, set lastIndex to 0.
  8. Let matcher be R.[[RegExpMatcher]].
  9. If flags contains "u" or flags contains "v", let fullUnicode be true; else let fullUnicode be false.
  10. Let matchSucceeded be false.
  11. If fullUnicode is true, let input be StringToCodePoints(S); otherwise let input be a List whose elements are the code units that are the elements of S.
  12. NOTE: Each element of input is considered to be a character.
  13. Repeat, while matchSucceeded is false,
    1. If lastIndex > length, then
      1. If global is true or sticky is true, then
        1. Perform ? Set(R, "lastIndex", +0𝔽, true).
      2. Return null.
    2. Let inputIndex be the index into input of the character that was obtained from element lastIndex of S.
    3. Let r be matcher(input, inputIndex).
    4. If r is failure, then
      1. If sticky is true, then
        1. Perform ? Set(R, "lastIndex", +0𝔽, true).
        2. Return null.
      2. Set lastIndex to AdvanceStringIndex(S, lastIndex, fullUnicode).
    5. Else,
      1. Assert: r is a MatchState.
      2. Set matchSucceeded to true.
  14. Let e be r.[[EndIndex]].
  15. If fullUnicode is true, set e to GetStringIndex(S, e).
  16. If global is true or sticky is true, then
    1. Perform ? Set(R, "lastIndex", 𝔽(e), true).
  17. Let n be the number of elements in r.[[Captures]].
  18. Assert: n = R.[[RegExpRecord]].[[CapturingGroupsCount]].
  19. Assert: n < 232 - 1.
  20. Let A be ! ArrayCreate(n + 1).
  21. Assert: The mathematical value of A's "length" property is n + 1.
  22. Perform ! CreateDataPropertyOrThrow(A, "index", 𝔽(lastIndex)).
  23. Perform ! CreateDataPropertyOrThrow(A, "input", S).
  24. Let match be the Match Record { [[StartIndex]]: lastIndex, [[EndIndex]]: e }.
  25. Let indices be a new empty List.
  26. Let groupNames be a new empty List.
  27. Append match to indices.
  28. Let matchedSubstr be GetMatchString(S, match).
  29. Perform ! CreateDataPropertyOrThrow(A, "0", matchedSubstr).
  30. If R contains any GroupName, then
    1. Let groups be OrdinaryObjectCreate(null).
    2. Let hasGroups be true.
  31. Else,
    1. Let groups be undefined.
    2. Let hasGroups be false.
  32. Perform ! CreateDataPropertyOrThrow(A, "groups", groups).
  33. Let matchedGroupNames be a new empty List.
  34. For each integer i such that 1 ≤ in, in ascending order, do
    1. Let captureI be ith element of r.[[Captures]].
    2. If captureI is undefined, then
      1. Let capturedValue be undefined.
      2. Append undefined to indices.
    3. Else,
      1. Let captureStart be captureI.[[StartIndex]].
      2. Let captureEnd be captureI.[[EndIndex]].
      3. If fullUnicode is true, then
        1. Set captureStart to GetStringIndex(S, captureStart).
        2. Set captureEnd to GetStringIndex(S, captureEnd).
      4. Let capture be the Match Record { [[StartIndex]]: captureStart, [[EndIndex]]: captureEnd }.
      5. Let capturedValue be GetMatchString(S, capture).
      6. Append capture to indices.
    4. Perform ! CreateDataPropertyOrThrow(A, ! ToString(𝔽(i)), capturedValue).
    5. If the ith capture of R was defined with a GroupName, then
      1. Let s be the CapturingGroupName of that GroupName.
      2. If matchedGroupNames contains s, then
        1. Assert: capturedValue is undefined.
        2. Append undefined to groupNames.
      3. Else,
        1. If capturedValue is not undefined, append s to matchedGroupNames.
        2. NOTE: If there are multiple groups named s, groups may already have an s property at this point. However, because groups is an ordinary object whose properties are all writable data properties, the call to CreateDataPropertyOrThrow is nevertheless guaranteed to succeed.
        3. Perform ! CreateDataPropertyOrThrow(groups, s, capturedValue).
        4. Append s to groupNames.
    6. Else,
      1. Append undefined to groupNames.
  35. If hasIndices is true, then
    1. Let indicesArray be MakeMatchIndicesIndexPairArray(S, indices, groupNames, hasGroups).
    2. Perform ! CreateDataPropertyOrThrow(A, "indices", indicesArray).
  36. Return A.

22.2.7.3 AdvanceStringIndex ( S, index, unicode )

The abstract operation AdvanceStringIndex takes arguments S (a String), index (a non-negative integer), and unicode (a Boolean) and returns an integer. It performs the following steps when called:

  1. Assert: index ≤ 253 - 1.
  2. If unicode is false, return index + 1.
  3. Let length be the length of S.
  4. If index + 1 ≥ length, return index + 1.
  5. Let cp be CodePointAt(S, index).
  6. Return index + cp.[[CodeUnitCount]].

22.2.7.4 GetStringIndex ( S, codePointIndex )

The abstract operation GetStringIndex takes arguments S (a String) and codePointIndex (a non-negative integer) and returns a non-negative integer. It interprets S as a sequence of UTF-16 encoded code points, as described in 6.1.4, and returns the code unit index corresponding to code point index codePointIndex when such an index exists. Otherwise, it returns the length of S. It performs the following steps when called:

  1. If S is the empty String, return 0.
  2. Let len be the length of S.
  3. Let codeUnitCount be 0.
  4. Let codePointCount be 0.
  5. Repeat, while codeUnitCount < len,
    1. If codePointCount = codePointIndex, return codeUnitCount.
    2. Let cp be CodePointAt(S, codeUnitCount).
    3. Set codeUnitCount to codeUnitCount + cp.[[CodeUnitCount]].
    4. Set codePointCount to codePointCount + 1.
  6. Return len.

22.2.7.5 Match Records

A Match Record is a Record value used to encapsulate the start and end indices of a regular expression match or capture.

Match Records have the fields listed in Table 72.

Table 72: Match Record Fields
Field Name Value Meaning
[[StartIndex]] a non-negative integer The number of code units from the start of a string at which the match begins (inclusive).
[[EndIndex]] an integer[[StartIndex]] The number of code units from the start of a string at which the match ends (exclusive).

22.2.7.6 GetMatchString ( S, match )

The abstract operation GetMatchString takes arguments S (a String) and match (a Match Record) and returns a String. It performs the following steps when called:

  1. Assert: match.[[StartIndex]]match.[[EndIndex]] ≤ the length of S.
  2. Return the substring of S from match.[[StartIndex]] to match.[[EndIndex]].

22.2.7.7 GetMatchIndexPair ( S, match )

The abstract operation GetMatchIndexPair takes arguments S (a String) and match (a Match Record) and returns an Array. It performs the following steps when called:

  1. Assert: match.[[StartIndex]]match.[[EndIndex]] ≤ the length of S.
  2. Return CreateArrayFromList𝔽(match.[[StartIndex]]), 𝔽(match.[[EndIndex]]) »).

22.2.7.8 MakeMatchIndicesIndexPairArray ( S, indices, groupNames, hasGroups )

The abstract operation MakeMatchIndicesIndexPairArray takes arguments S (a String), indices (a List of either Match Records or undefined), groupNames (a List of either Strings or undefined), and hasGroups (a Boolean) and returns an Array. It performs the following steps when called:

  1. Let n be the number of elements in indices.
  2. Assert: n < 232 - 1.
  3. Assert: groupNames has n - 1 elements.
  4. NOTE: The groupNames List contains elements aligned with the indices List starting at indices[1].
  5. Let A be ! ArrayCreate(n).
  6. If hasGroups is true, then
    1. Let groups be OrdinaryObjectCreate(null).
  7. Else,
    1. Let groups be undefined.
  8. Perform ! CreateDataPropertyOrThrow(A, "groups", groups).
  9. For each integer i such that 0 ≤ i < n, in ascending order, do
    1. Let matchIndices be indices[i].
    2. If matchIndices is not undefined, then
      1. Let matchIndexPair be GetMatchIndexPair(S, matchIndices).
    3. Else,
      1. Let matchIndexPair be undefined.
    4. Perform ! CreateDataPropertyOrThrow(A, ! ToString(𝔽(i)), matchIndexPair).
    5. If i > 0, then
      1. Let s be groupNames[i - 1].
      2. If s is not undefined, then
        1. Assert: groups is not undefined.
        2. NOTE: If there are multiple groups named s, groups may already have an s property at this point. However, because groups is an ordinary object whose properties are all writable data properties, the call to CreateDataPropertyOrThrow is nevertheless guaranteed to succeed.
        3. Perform ! CreateDataPropertyOrThrow(groups, s, matchIndexPair).
  10. Return A.

22.2.8 Properties of RegExp Instances

RegExp instances are ordinary objects that inherit properties from the RegExp prototype object. RegExp instances have internal slots [[OriginalSource]], [[OriginalFlags]], [[RegExpRecord]], and [[RegExpMatcher]]. The value of the [[RegExpMatcher]] internal slot is an Abstract Closure representation of the Pattern of the RegExp object.

Note

Prior to ECMAScript 2015, RegExp instances were specified as having the own data properties "source", "global", "ignoreCase", and "multiline". Those properties are now specified as accessor properties of RegExp.prototype.

RegExp instances also have the following property:

22.2.8.1 lastIndex

The value of the "lastIndex" property specifies the String index at which to start the next match. It is coerced to an integral Number when used (see 22.2.7.2). This property shall have the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }.

22.2.9 RegExp String Iterator Objects

A RegExp String Iterator is an object that represents a specific iteration over some specific String instance object, matching against some specific RegExp instance object. There is not a named constructor for RegExp String Iterator objects. Instead, RegExp String Iterator objects are created by calling certain methods of RegExp instance objects.

22.2.9.1 CreateRegExpStringIterator ( R, S, global, fullUnicode )

The abstract operation CreateRegExpStringIterator takes arguments R (an Object), S (a String), global (a Boolean), and fullUnicode (a Boolean) and returns an Object. It performs the following steps when called:

  1. Let iterator be OrdinaryObjectCreate(%RegExpStringIteratorPrototype%, « [[IteratingRegExp]], [[IteratedString]], [[Global]], [[Unicode]], [[Done]] »).
  2. Set iterator.[[IteratingRegExp]] to R.
  3. Set iterator.[[IteratedString]] to S.
  4. Set iterator.[[Global]] to global.
  5. Set iterator.[[Unicode]] to fullUnicode.
  6. Set iterator.[[Done]] to false.
  7. Return iterator.

22.2.9.2 The %RegExpStringIteratorPrototype% Object

The %RegExpStringIteratorPrototype% object:

22.2.9.2.1 %RegExpStringIteratorPrototype%.next ( )

  1. Let O be the this value.
  2. If O is not an Object, throw a TypeError exception.
  3. If O does not have all of the internal slots of a RegExp String Iterator Object Instance (see 22.2.9.3), throw a TypeError exception.
  4. If O.[[Done]] is true, then
    1. Return CreateIteratorResultObject(undefined, true).
  5. Let R be O.[[IteratingRegExp]].
  6. Let S be O.[[IteratedString]].
  7. Let global be O.[[Global]].
  8. Let fullUnicode be O.[[Unicode]].
  9. Let match be ? RegExpExec(R, S).
  10. If match is null, then
    1. Set O.[[Done]] to true.
    2. Return CreateIteratorResultObject(undefined, true).
  11. If global is false, then
    1. Set O.[[Done]] to true.
    2. Return CreateIteratorResultObject(match, false).
  12. Let matchStr be ? ToString(? Get(match, "0")).
  13. If matchStr is the empty String, then
    1. Let thisIndex be (? ToLength(? Get(R, "lastIndex"))).
    2. Let nextIndex be AdvanceStringIndex(S, thisIndex, fullUnicode).
    3. Perform ? Set(R, "lastIndex", 𝔽(nextIndex), true).
  14. Return CreateIteratorResultObject(match, false).

22.2.9.2.2 %RegExpStringIteratorPrototype% [ %Symbol.toStringTag% ]

The initial value of the %Symbol.toStringTag% property is the String value "RegExp String Iterator".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

22.2.9.3 Properties of RegExp String Iterator Instances

RegExp String Iterator instances are ordinary objects that inherit properties from the %RegExpStringIteratorPrototype% intrinsic object. RegExp String Iterator instances are initially created with the internal slots listed in Table 73.

Table 73: Internal Slots of RegExp String Iterator Instances
Internal Slot Type Description
[[IteratingRegExp]] an Object The regular expression used for iteration. IsRegExp([[IteratingRegExp]]) is initially true.
[[IteratedString]] a String The String value being iterated upon.
[[Global]] a Boolean Indicates whether the [[IteratingRegExp]] is global or not.
[[Unicode]] a Boolean Indicates whether the [[IteratingRegExp]] is in Unicode mode or not.
[[Done]] a Boolean Indicates whether the iteration is complete or not.

23 Indexed Collections

23.1 Array Objects

Arrays are exotic objects that give special treatment to a certain class of property names. See 10.4.2 for a definition of this special treatment.

23.1.1 The Array Constructor

The Array constructor:

  • is %Array%.
  • is the initial value of the "Array" property of the global object.
  • creates and initializes a new Array when called as a constructor.
  • also creates and initializes a new Array when called as a function rather than as a constructor. Thus the function call Array(…) is equivalent to the object creation expression new Array(…) with the same arguments.
  • is a function whose behaviour differs based upon the number and types of its arguments.
  • may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the exotic Array behaviour must include a super call to the Array constructor to initialize subclass instances that are Array exotic objects. However, most of the Array.prototype methods are generic methods that are not dependent upon their this value being an Array exotic object.

23.1.1.1 Array ( ...values )

This function performs the following steps when called:

  1. If NewTarget is undefined, let newTarget be the active function object; else let newTarget be NewTarget.
  2. Let proto be ? GetPrototypeFromConstructor(newTarget, "%Array.prototype%").
  3. Let numberOfArgs be the number of elements in values.
  4. If numberOfArgs = 0, then
    1. Return ! ArrayCreate(0, proto).
  5. Else if numberOfArgs = 1, then
    1. Let len be values[0].
    2. Let array be ! ArrayCreate(0, proto).
    3. If len is not a Number, then
      1. Perform ! CreateDataPropertyOrThrow(array, "0", len).
      2. Let intLen be 1𝔽.
    4. Else,
      1. Let intLen be ! ToUint32(len).
      2. If SameValueZero(intLen, len) is false, throw a RangeError exception.
    5. Perform ! Set(array, "length", intLen, true).
    6. Return array.
  6. Else,
    1. Assert: numberOfArgs ≥ 2.
    2. Let array be ? ArrayCreate(numberOfArgs, proto).
    3. Let k be 0.
    4. Repeat, while k < numberOfArgs,
      1. Let Pk be ! ToString(𝔽(k)).
      2. Let itemK be values[k].
      3. Perform ! CreateDataPropertyOrThrow(array, Pk, itemK).
      4. Set k to k + 1.
    5. Assert: The mathematical value of array's "length" property is numberOfArgs.
    6. Return array.

23.1.2 Properties of the Array Constructor

The Array constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has a "length" property whose value is 1𝔽.
  • has the following properties:

23.1.2.1 Array.from ( items [ , mapper [ , thisArg ] ] )

This method performs the following steps when called:

  1. Let C be the this value.
  2. If mapper is undefined, then
    1. Let mapping be false.
  3. Else,
    1. If IsCallable(mapper) is false, throw a TypeError exception.
    2. Let mapping be true.
  4. Let usingIterator be ? GetMethod(items, %Symbol.iterator%).
  5. If usingIterator is not undefined, then
    1. If IsConstructor(C) is true, then
      1. Let A be ? Construct(C).
    2. Else,
      1. Let A be ! ArrayCreate(0).
    3. Let iteratorRecord be ? GetIteratorFromMethod(items, usingIterator).
    4. Let k be 0.
    5. Repeat,
      1. If k ≥ 253 - 1, then
        1. Let error be ThrowCompletion(a newly created TypeError object).
        2. Return ? IteratorClose(iteratorRecord, error).
      2. Let Pk be ! ToString(𝔽(k)).
      3. Let next be ? IteratorStepValue(iteratorRecord).
      4. If next is done, then
        1. Perform ? Set(A, "length", 𝔽(k), true).
        2. Return A.
      5. If mapping is true, then
        1. Let mappedValue be Completion(Call(mapper, thisArg, « next, 𝔽(k) »)).
        2. IfAbruptCloseIterator(mappedValue, iteratorRecord).
      6. Else,
        1. Let mappedValue be next.
      7. Let defineStatus be Completion(CreateDataPropertyOrThrow(A, Pk, mappedValue)).
      8. IfAbruptCloseIterator(defineStatus, iteratorRecord).
      9. Set k to k + 1.
  6. NOTE: items is not iterable so assume it is an array-like object.
  7. Let arrayLike be ! ToObject(items).
  8. Let len be ? LengthOfArrayLike(arrayLike).
  9. If IsConstructor(C) is true, then
    1. Let A be ? Construct(C, « 𝔽(len) »).
  10. Else,
    1. Let A be ? ArrayCreate(len).
  11. Let k be 0.
  12. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kValue be ? Get(arrayLike, Pk).
    3. If mapping is true, then
      1. Let mappedValue be ? Call(mapper, thisArg, « kValue, 𝔽(k) »).
    4. Else,
      1. Let mappedValue be kValue.
    5. Perform ? CreateDataPropertyOrThrow(A, Pk, mappedValue).
    6. Set k to k + 1.
  13. Perform ? Set(A, "length", 𝔽(len), true).
  14. Return A.
Note

This method is an intentionally generic factory method; it does not require that its this value be the Array constructor. Therefore it can be transferred to or inherited by any other constructors that may be called with a single numeric argument.

23.1.2.2 Array.isArray ( arg )

This function performs the following steps when called:

  1. Return ? IsArray(arg).

23.1.2.3 Array.of ( ...items )

This method performs the following steps when called:

  1. Let len be the number of elements in items.
  2. Let lenNumber be 𝔽(len).
  3. Let C be the this value.
  4. If IsConstructor(C) is true, then
    1. Let A be ? Construct(C, « lenNumber »).
  5. Else,
    1. Let A be ? ArrayCreate(len).
  6. Let k be 0.
  7. Repeat, while k < len,
    1. Let kValue be items[k].
    2. Let Pk be ! ToString(𝔽(k)).
    3. Perform ? CreateDataPropertyOrThrow(A, Pk, kValue).
    4. Set k to k + 1.
  8. Perform ? Set(A, "length", lenNumber, true).
  9. Return A.
Note

This method is an intentionally generic factory method; it does not require that its this value be the Array constructor. Therefore it can be transferred to or inherited by other constructors that may be called with a single numeric argument.

23.1.2.4 Array.prototype

The value of Array.prototype is the Array prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

23.1.2.5 get Array [ %Symbol.species% ]

Array[%Symbol.species%] is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Return the this value.

The value of the "name" property of this function is "get [Symbol.species]".

Note

Array prototype methods normally use their this value's constructor to create a derived object. However, a subclass constructor may over-ride that default behaviour by redefining its %Symbol.species% property.

23.1.3 Properties of the Array Prototype Object

The Array prototype object:

  • is %Array.prototype%.
  • is an Array exotic object and has the internal methods specified for such objects.
  • has a "length" property whose initial value is +0𝔽 and whose attributes are { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.
Note

The Array prototype object is specified to be an Array exotic object to ensure compatibility with ECMAScript code that was created prior to the ECMAScript 2015 specification.

23.1.3.1 Array.prototype.at ( index )

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. Let relativeIndex be ? ToIntegerOrInfinity(index).
  4. If relativeIndex ≥ 0, then
    1. Let k be relativeIndex.
  5. Else,
    1. Let k be len + relativeIndex.
  6. If k < 0 or klen, return undefined.
  7. Return ? Get(O, ! ToString(𝔽(k))).

23.1.3.2 Array.prototype.concat ( ...items )

This method returns an array containing the array elements of the object followed by the array elements of each argument.

It performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let A be ? ArraySpeciesCreate(O, 0).
  3. Let n be 0.
  4. Prepend O to items.
  5. For each element E of items, do
    1. Let spreadable be ? IsConcatSpreadable(E).
    2. If spreadable is true, then
      1. Let len be ? LengthOfArrayLike(E).
      2. If n + len > 253 - 1, throw a TypeError exception.
      3. Let k be 0.
      4. Repeat, while k < len,
        1. Let Pk be ! ToString(𝔽(k)).
        2. Let exists be ? HasProperty(E, Pk).
        3. If exists is true, then
          1. Let subElement be ? Get(E, Pk).
          2. Perform ? CreateDataPropertyOrThrow(A, ! ToString(𝔽(n)), subElement).
        4. Set n to n + 1.
        5. Set k to k + 1.
    3. Else,
      1. NOTE: E is added as a single item rather than spread.
      2. If n ≥ 253 - 1, throw a TypeError exception.
      3. Perform ? CreateDataPropertyOrThrow(A, ! ToString(𝔽(n)), E).
      4. Set n to n + 1.
  6. Perform ? Set(A, "length", 𝔽(n), true).
  7. Return A.

The "length" property of this method is 1𝔽.

Note 1

The explicit setting of the "length" property in step 6 is intended to ensure the length is correct when the final non-empty element of items has trailing holes or when A is not a built-in Array.

Note 2

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.2.1 IsConcatSpreadable ( O )

The abstract operation IsConcatSpreadable takes argument O (an ECMAScript language value) and returns either a normal completion containing a Boolean or a throw completion. It performs the following steps when called:

  1. If O is not an Object, return false.
  2. Let spreadable be ? Get(O, %Symbol.isConcatSpreadable%).
  3. If spreadable is not undefined, return ToBoolean(spreadable).
  4. Return ? IsArray(O).

23.1.3.3 Array.prototype.constructor

The initial value of Array.prototype.constructor is %Array%.

23.1.3.4 Array.prototype.copyWithin ( target, start [ , end ] )

Note 1

The end argument is optional. If it is not provided, the length of the this value is used.

Note 2

If target is negative, it is treated as length + target where length is the length of the array. If start is negative, it is treated as length + start. If end is negative, it is treated as length + end.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. Let relativeTarget be ? ToIntegerOrInfinity(target).
  4. If relativeTarget = -∞, let to be 0.
  5. Else if relativeTarget < 0, let to be max(len + relativeTarget, 0).
  6. Else, let to be min(relativeTarget, len).
  7. Let relativeStart be ? ToIntegerOrInfinity(start).
  8. If relativeStart = -∞, let from be 0.
  9. Else if relativeStart < 0, let from be max(len + relativeStart, 0).
  10. Else, let from be min(relativeStart, len).
  11. If end is undefined, let relativeEnd be len; else let relativeEnd be ? ToIntegerOrInfinity(end).
  12. If relativeEnd = -∞, let final be 0.
  13. Else if relativeEnd < 0, let final be max(len + relativeEnd, 0).
  14. Else, let final be min(relativeEnd, len).
  15. Let count be min(final - from, len - to).
  16. If from < to and to < from + count, then
    1. Let direction be -1.
    2. Set from to from + count - 1.
    3. Set to to to + count - 1.
  17. Else,
    1. Let direction be 1.
  18. Repeat, while count > 0,
    1. Let fromKey be ! ToString(𝔽(from)).
    2. Let toKey be ! ToString(𝔽(to)).
    3. Let fromPresent be ? HasProperty(O, fromKey).
    4. If fromPresent is true, then
      1. Let fromValue be ? Get(O, fromKey).
      2. Perform ? Set(O, toKey, fromValue, true).
    5. Else,
      1. Assert: fromPresent is false.
      2. Perform ? DeletePropertyOrThrow(O, toKey).
    6. Set from to from + direction.
    7. Set to to to + direction.
    8. Set count to count - 1.
  19. Return O.
Note 3

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.5 Array.prototype.entries ( )

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Return CreateArrayIterator(O, key+value).

23.1.3.6 Array.prototype.every ( callback [ , thisArg ] )

Note 1

callback should be a function that accepts three arguments and returns a value that is coercible to a Boolean value. every calls callback once for each element present in the array, in ascending order, until it finds one where callback returns false. If such an element is found, every immediately returns false. Otherwise, every returns true. callback is called only for elements of the array which actually exist; it is not called for missing elements of the array.

If a thisArg parameter is provided, it will be used as the this value for each invocation of callback. If it is not provided, undefined is used instead.

callback is called with three arguments: the value of the element, the index of the element, and the object being traversed.

every does not directly mutate the object on which it is called but the object may be mutated by the calls to callback.

The range of elements processed by every is set before the first call to callback. Elements which are appended to the array after the call to every begins will not be visited by callback. If existing elements of the array are changed, their value as passed to callback will be the value at the time every visits them; elements that are deleted after the call to every begins and before being visited are not visited. every acts like the "for all" quantifier in mathematics. In particular, for an empty array, it returns true.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. If IsCallable(callback) is false, throw a TypeError exception.
  4. Let k be 0.
  5. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kPresent be ? HasProperty(O, Pk).
    3. If kPresent is true, then
      1. Let kValue be ? Get(O, Pk).
      2. Let testResult be ToBoolean(? Call(callback, thisArg, « kValue, 𝔽(k), O »)).
      3. If testResult is false, return false.
    4. Set k to k + 1.
  6. Return true.
Note 2

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.7 Array.prototype.fill ( value [ , start [ , end ] ] )

Note 1

The start argument is optional. If it is not provided, +0𝔽 is used.

The end argument is optional. If it is not provided, the length of the this value is used.

Note 2

If start is negative, it is treated as length + start where length is the length of the array. If end is negative, it is treated as length + end.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. Let relativeStart be ? ToIntegerOrInfinity(start).
  4. If relativeStart = -∞, let k be 0.
  5. Else if relativeStart < 0, let k be max(len + relativeStart, 0).
  6. Else, let k be min(relativeStart, len).
  7. If end is undefined, let relativeEnd be len; else let relativeEnd be ? ToIntegerOrInfinity(end).
  8. If relativeEnd = -∞, let final be 0.
  9. Else if relativeEnd < 0, let final be max(len + relativeEnd, 0).
  10. Else, let final be min(relativeEnd, len).
  11. Repeat, while k < final,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Perform ? Set(O, Pk, value, true).
    3. Set k to k + 1.
  12. Return O.
Note 3

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.8 Array.prototype.filter ( callback [ , thisArg ] )

Note 1

callback should be a function that accepts three arguments and returns a value that is coercible to a Boolean value. filter calls callback once for each element in the array, in ascending order, and constructs a new array of all the values for which callback returns true. callback is called only for elements of the array which actually exist; it is not called for missing elements of the array.

If a thisArg parameter is provided, it will be used as the this value for each invocation of callback. If it is not provided, undefined is used instead.

callback is called with three arguments: the value of the element, the index of the element, and the object being traversed.

filter does not directly mutate the object on which it is called but the object may be mutated by the calls to callback.

The range of elements processed by filter is set before the first call to callback. Elements which are appended to the array after the call to filter begins will not be visited by callback. If existing elements of the array are changed their value as passed to callback will be the value at the time filter visits them; elements that are deleted after the call to filter begins and before being visited are not visited.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. If IsCallable(callback) is false, throw a TypeError exception.
  4. Let A be ? ArraySpeciesCreate(O, 0).
  5. Let k be 0.
  6. Let to be 0.
  7. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kPresent be ? HasProperty(O, Pk).
    3. If kPresent is true, then
      1. Let kValue be ? Get(O, Pk).
      2. Let selected be ToBoolean(? Call(callback, thisArg, « kValue, 𝔽(k), O »)).
      3. If selected is true, then
        1. Perform ? CreateDataPropertyOrThrow(A, ! ToString(𝔽(to)), kValue).
        2. Set to to to + 1.
    4. Set k to k + 1.
  8. Return A.
Note 2

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.9 Array.prototype.find ( predicate [ , thisArg ] )

Note 1

This method calls predicate once for each element of the array, in ascending index order, until it finds one where predicate returns a value that coerces to true. If such an element is found, find immediately returns that element value. Otherwise, find returns undefined.

See FindViaPredicate for additional information.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. Let findRec be ? FindViaPredicate(O, len, ascending, predicate, thisArg).
  4. Return findRec.[[Value]].
Note 2

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.10 Array.prototype.findIndex ( predicate [ , thisArg ] )

Note 1

This method calls predicate once for each element of the array, in ascending index order, until it finds one where predicate returns a value that coerces to true. If such an element is found, findIndex immediately returns the index of that element value. Otherwise, findIndex returns -1.

See FindViaPredicate for additional information.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. Let findRec be ? FindViaPredicate(O, len, ascending, predicate, thisArg).
  4. Return findRec.[[Index]].
Note 2

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.11 Array.prototype.findLast ( predicate [ , thisArg ] )

Note 1

This method calls predicate once for each element of the array, in descending index order, until it finds one where predicate returns a value that coerces to true. If such an element is found, findLast immediately returns that element value. Otherwise, findLast returns undefined.

See FindViaPredicate for additional information.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. Let findRec be ? FindViaPredicate(O, len, descending, predicate, thisArg).
  4. Return findRec.[[Value]].
Note 2

This method is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.12 Array.prototype.findLastIndex ( predicate [ , thisArg ] )

Note 1

This method calls predicate once for each element of the array, in descending index order, until it finds one where predicate returns a value that coerces to true. If such an element is found, findLastIndex immediately returns the index of that element value. Otherwise, findLastIndex returns -1.

See FindViaPredicate for additional information.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. Let findRec be ? FindViaPredicate(O, len, descending, predicate, thisArg).
  4. Return findRec.[[Index]].
Note 2

This method is intentionally generic; it does not require that its this value be an Array object. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.12.1 FindViaPredicate ( O, len, direction, predicate, thisArg )

The abstract operation FindViaPredicate takes arguments O (an Object), len (a non-negative integer), direction (ascending or descending), predicate (an ECMAScript language value), and thisArg (an ECMAScript language value) and returns either a normal completion containing a Record with fields [[Index]] (an integral Number) and [[Value]] (an ECMAScript language value) or a throw completion.

O should be an array-like object or a TypedArray. This operation calls predicate once for each element of O, in either ascending index order or descending index order (as indicated by direction), until it finds one where predicate returns a value that coerces to true. At that point, this operation returns a Record that gives the index and value of the element found. If no such element is found, this operation returns a Record that specifies -1𝔽 for the index and undefined for the value.

predicate should be a function. When called for an element of the array, it is passed three arguments: the value of the element, the index of the element, and the object being traversed. Its return value will be coerced to a Boolean value.

thisArg will be used as the this value for each invocation of predicate.

This operation does not directly mutate the object on which it is called, but the object may be mutated by the calls to predicate.

The range of elements processed is set before the first call to predicate, just before the traversal begins. Elements that are appended to the array after this will not be visited by predicate. If existing elements of the array are changed, their value as passed to predicate will be the value at the time that this operation visits them. Elements that are deleted after traversal begins and before being visited are still visited and are either looked up from the prototype or are undefined.

It performs the following steps when called:

  1. If IsCallable(predicate) is false, throw a TypeError exception.
  2. If direction is ascending, then
    1. Let indices be a List of the integers in the interval from 0 (inclusive) to len (exclusive), in ascending order.
  3. Else,
    1. Let indices be a List of the integers in the interval from 0 (inclusive) to len (exclusive), in descending order.
  4. For each integer k of indices, do
    1. Let Pk be ! ToString(𝔽(k)).
    2. NOTE: If O is a TypedArray, the following invocation of Get will return a normal completion.
    3. Let kValue be ? Get(O, Pk).
    4. Let testResult be ? Call(predicate, thisArg, « kValue, 𝔽(k), O »).
    5. If ToBoolean(testResult) is true, return the Record { [[Index]]: 𝔽(k), [[Value]]: kValue }.
  5. Return the Record { [[Index]]: -1𝔽, [[Value]]: undefined }.

23.1.3.13 Array.prototype.flat ( [ depth ] )

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let sourceLen be ? LengthOfArrayLike(O).
  3. Let depthNum be 1.
  4. If depth is not undefined, then
    1. Set depthNum to ? ToIntegerOrInfinity(depth).
    2. If depthNum < 0, set depthNum to 0.
  5. Let A be ? ArraySpeciesCreate(O, 0).
  6. Perform ? FlattenIntoArray(A, O, sourceLen, 0, depthNum).
  7. Return A.

23.1.3.13.1 FlattenIntoArray ( target, source, sourceLen, start, depth [ , mapperFunction [ , thisArg ] ] )

The abstract operation FlattenIntoArray takes arguments target (an Object), source (an Object), sourceLen (a non-negative integer), start (a non-negative integer), and depth (a non-negative integer or +∞) and optional arguments mapperFunction (a function object) and thisArg (an ECMAScript language value) and returns either a normal completion containing a non-negative integer or a throw completion. It performs the following steps when called:

  1. Assert: If mapperFunction is present, then IsCallable(mapperFunction) is true, thisArg is present, and depth is 1.
  2. Let targetIndex be start.
  3. Let sourceIndex be +0𝔽.
  4. Repeat, while (sourceIndex) < sourceLen,
    1. Let P be ! ToString(sourceIndex).
    2. Let exists be ? HasProperty(source, P).
    3. If exists is true, then
      1. Let element be ? Get(source, P).
      2. If mapperFunction is present, then
        1. Set element to ? Call(mapperFunction, thisArg, « element, sourceIndex, source »).
      3. Let shouldFlatten be false.
      4. If depth > 0, then
        1. Set shouldFlatten to ? IsArray(element).
      5. If shouldFlatten is true, then
        1. If depth = +∞, let newDepth be +∞.
        2. Else, let newDepth be depth - 1.
        3. Let elementLen be ? LengthOfArrayLike(element).
        4. Set targetIndex to ? FlattenIntoArray(target, element, elementLen, targetIndex, newDepth).
      6. Else,
        1. If targetIndex ≥ 253 - 1, throw a TypeError exception.
        2. Perform ? CreateDataPropertyOrThrow(target, ! ToString(𝔽(targetIndex)), element).
        3. Set targetIndex to targetIndex + 1.
    4. Set sourceIndex to sourceIndex + 1𝔽.
  5. Return targetIndex.

23.1.3.14 Array.prototype.flatMap ( mapperFunction [ , thisArg ] )

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let sourceLen be ? LengthOfArrayLike(O).
  3. If IsCallable(mapperFunction) is false, throw a TypeError exception.
  4. Let A be ? ArraySpeciesCreate(O, 0).
  5. Perform ? FlattenIntoArray(A, O, sourceLen, 0, 1, mapperFunction, thisArg).
  6. Return A.

23.1.3.15 Array.prototype.forEach ( callback [ , thisArg ] )

Note 1

callback should be a function that accepts three arguments. forEach calls callback once for each element present in the array, in ascending order. callback is called only for elements of the array which actually exist; it is not called for missing elements of the array.

If a thisArg parameter is provided, it will be used as the this value for each invocation of callback. If it is not provided, undefined is used instead.

callback is called with three arguments: the value of the element, the index of the element, and the object being traversed.

forEach does not directly mutate the object on which it is called but the object may be mutated by the calls to callback.

The range of elements processed by forEach is set before the first call to callback. Elements which are appended to the array after the call to forEach begins will not be visited by callback. If existing elements of the array are changed, their value as passed to callback will be the value at the time forEach visits them; elements that are deleted after the call to forEach begins and before being visited are not visited.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. If IsCallable(callback) is false, throw a TypeError exception.
  4. Let k be 0.
  5. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kPresent be ? HasProperty(O, Pk).
    3. If kPresent is true, then
      1. Let kValue be ? Get(O, Pk).
      2. Perform ? Call(callback, thisArg, « kValue, 𝔽(k), O »).
    4. Set k to k + 1.
  6. Return undefined.
Note 2

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.16 Array.prototype.includes ( searchElement [ , fromIndex ] )

Note 1

This method compares searchElement to the elements of the array, in ascending order, using the SameValueZero algorithm, and if found at any position, returns true; otherwise, it returns false.

The optional second argument fromIndex defaults to +0𝔽 (i.e. the whole array is searched). If it is greater than or equal to the length of the array, false is returned, i.e. the array will not be searched. If it is less than -0𝔽, it is used as the offset from the end of the array to compute fromIndex. If the computed index is less than or equal to +0𝔽, the whole array will be searched.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. If len = 0, return false.
  4. Let n be ? ToIntegerOrInfinity(fromIndex).
  5. Assert: If fromIndex is undefined, then n is 0.
  6. If n = +∞, return false.
  7. Else if n = -∞, set n to 0.
  8. If n ≥ 0, then
    1. Let k be n.
  9. Else,
    1. Let k be len + n.
    2. If k < 0, set k to 0.
  10. Repeat, while k < len,
    1. Let elementK be ? Get(O, ! ToString(𝔽(k))).
    2. If SameValueZero(searchElement, elementK) is true, return true.
    3. Set k to k + 1.
  11. Return false.
Note 2

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

Note 3

This method intentionally differs from the similar indexOf method in two ways. First, it uses the SameValueZero algorithm, instead of IsStrictlyEqual, allowing it to detect NaN array elements. Second, it does not skip missing array elements, instead treating them as undefined.

23.1.3.17 Array.prototype.indexOf ( searchElement [ , fromIndex ] )

This method compares searchElement to the elements of the array, in ascending order, using the IsStrictlyEqual algorithm, and if found at one or more indices, returns the smallest such index; otherwise, it returns -1𝔽.

Note 1

The optional second argument fromIndex defaults to +0𝔽 (i.e. the whole array is searched). If it is greater than or equal to the length of the array, -1𝔽 is returned, i.e. the array will not be searched. If it is less than -0𝔽, it is used as the offset from the end of the array to compute fromIndex. If the computed index is less than or equal to +0𝔽, the whole array will be searched.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. If len = 0, return -1𝔽.
  4. Let n be ? ToIntegerOrInfinity(fromIndex).
  5. Assert: If fromIndex is undefined, then n is 0.
  6. If n = +∞, return -1𝔽.
  7. Else if n = -∞, set n to 0.
  8. If n ≥ 0, then
    1. Let k be n.
  9. Else,
    1. Let k be len + n.
    2. If k < 0, set k to 0.
  10. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kPresent be ? HasProperty(O, Pk).
    3. If kPresent is true, then
      1. Let elementK be ? Get(O, Pk).
      2. If IsStrictlyEqual(searchElement, elementK) is true, return 𝔽(k).
    4. Set k to k + 1.
  11. Return -1𝔽.
Note 2

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.18 Array.prototype.join ( separator )

This method converts the elements of the array to Strings, and then concatenates these Strings, separated by occurrences of the separator. If no separator is provided, a single comma is used as the separator.

It performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. If separator is undefined, let sep be ",".
  4. Else, let sep be ? ToString(separator).
  5. Let R be the empty String.
  6. Let k be 0.
  7. Repeat, while k < len,
    1. If k > 0, set R to the string-concatenation of R and sep.
    2. Let element be ? Get(O, ! ToString(𝔽(k))).
    3. If element is neither undefined nor null, then
      1. Let S be ? ToString(element).
      2. Set R to the string-concatenation of R and S.
    4. Set k to k + 1.
  8. Return R.
Note

This method is intentionally generic; it does not require that its this value be an Array. Therefore, it can be transferred to other kinds of objects for use as a method.

23.1.3.19 Array.prototype.keys ( )

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Return CreateArrayIterator(O, key).

23.1.3.20 Array.prototype.lastIndexOf ( searchElement [ , fromIndex ] )

Note 1

This method compares searchElement to the elements of the array in descending order using the IsStrictlyEqual algorithm, and if found at one or more indices, returns the largest such index; otherwise, it returns -1𝔽.

The optional second argument fromIndex defaults to the array's length minus one (i.e. the whole array is searched). If it is greater than or equal to the length of the array, the whole array will be searched. If it is less than -0𝔽, it is used as the offset from the end of the array to compute fromIndex. If the computed index is less than or equal to +0𝔽, -1𝔽 is returned.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. If len = 0, return -1𝔽.
  4. If fromIndex is present, let n be ? ToIntegerOrInfinity(fromIndex); else let n be len - 1.
  5. If n = -∞, return -1𝔽.
  6. If n ≥ 0, then
    1. Let k be min(n, len - 1).
  7. Else,
    1. Let k be len + n.
  8. Repeat, while k ≥ 0,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kPresent be ? HasProperty(O, Pk).
    3. If kPresent is true, then
      1. Let elementK be ? Get(O, Pk).
      2. If IsStrictlyEqual(searchElement, elementK) is true, return 𝔽(k).
    4. Set k to k - 1.
  9. Return -1𝔽.
Note 2

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.21 Array.prototype.map ( callback [ , thisArg ] )

Note 1

callback should be a function that accepts three arguments. map calls callback once for each element in the array, in ascending order, and constructs a new Array from the results. callback is called only for elements of the array which actually exist; it is not called for missing elements of the array.

If a thisArg parameter is provided, it will be used as the this value for each invocation of callback. If it is not provided, undefined is used instead.

callback is called with three arguments: the value of the element, the index of the element, and the object being traversed.

map does not directly mutate the object on which it is called but the object may be mutated by the calls to callback.

The range of elements processed by map is set before the first call to callback. Elements which are appended to the array after the call to map begins will not be visited by callback. If existing elements of the array are changed, their value as passed to callback will be the value at the time map visits them; elements that are deleted after the call to map begins and before being visited are not visited.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. If IsCallable(callback) is false, throw a TypeError exception.
  4. Let A be ? ArraySpeciesCreate(O, len).
  5. Let k be 0.
  6. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kPresent be ? HasProperty(O, Pk).
    3. If kPresent is true, then
      1. Let kValue be ? Get(O, Pk).
      2. Let mappedValue be ? Call(callback, thisArg, « kValue, 𝔽(k), O »).
      3. Perform ? CreateDataPropertyOrThrow(A, Pk, mappedValue).
    4. Set k to k + 1.
  7. Return A.
Note 2

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.22 Array.prototype.pop ( )

Note 1

This method removes the last element of the array and returns it.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. If len = 0, then
    1. Perform ? Set(O, "length", +0𝔽, true).
    2. Return undefined.
  4. Else,
    1. Assert: len > 0.
    2. Let newLen be 𝔽(len - 1).
    3. Let index be ! ToString(newLen).
    4. Let element be ? Get(O, index).
    5. Perform ? DeletePropertyOrThrow(O, index).
    6. Perform ? Set(O, "length", newLen, true).
    7. Return element.
Note 2

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.23 Array.prototype.push ( ...items )

Note 1

This method appends the arguments to the end of the array, in the order in which they appear. It returns the new length of the array.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. Let argCount be the number of elements in items.
  4. If len + argCount > 253 - 1, throw a TypeError exception.
  5. For each element E of items, do
    1. Perform ? Set(O, ! ToString(𝔽(len)), E, true).
    2. Set len to len + 1.
  6. Perform ? Set(O, "length", 𝔽(len), true).
  7. Return 𝔽(len).

The "length" property of this method is 1𝔽.

Note 2

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.24 Array.prototype.reduce ( callback [ , initialValue ] )

Note 1

callback should be a function that takes four arguments. reduce calls the callback, as a function, once for each element after the first element present in the array, in ascending order.

callback is called with four arguments: the previousValue (value from the previous call to callback), the currentValue (value of the current element), the currentIndex, and the object being traversed. The first time that callback is called, the previousValue and currentValue can be one of two values. If an initialValue was supplied in the call to reduce, then previousValue will be initialValue and currentValue will be the first value in the array. If no initialValue was supplied, then previousValue will be the first value in the array and currentValue will be the second. It is a TypeError if the array contains no elements and initialValue is not provided.

reduce does not directly mutate the object on which it is called but the object may be mutated by the calls to callback.

The range of elements processed by reduce is set before the first call to callback. Elements that are appended to the array after the call to reduce begins will not be visited by callback. If existing elements of the array are changed, their value as passed to callback will be the value at the time reduce visits them; elements that are deleted after the call to reduce begins and before being visited are not visited.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. If IsCallable(callback) is false, throw a TypeError exception.
  4. If len = 0 and initialValue is not present, throw a TypeError exception.
  5. Let k be 0.
  6. Let accumulator be undefined.
  7. If initialValue is present, then
    1. Set accumulator to initialValue.
  8. Else,
    1. Let kPresent be false.
    2. Repeat, while kPresent is false and k < len,
      1. Let Pk be ! ToString(𝔽(k)).
      2. Set kPresent to ? HasProperty(O, Pk).
      3. If kPresent is true, then
        1. Set accumulator to ? Get(O, Pk).
      4. Set k to k + 1.
    3. If kPresent is false, throw a TypeError exception.
  9. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kPresent be ? HasProperty(O, Pk).
    3. If kPresent is true, then
      1. Let kValue be ? Get(O, Pk).
      2. Set accumulator to ? Call(callback, undefined, « accumulator, kValue, 𝔽(k), O »).
    4. Set k to k + 1.
  10. Return accumulator.
Note 2

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.25 Array.prototype.reduceRight ( callback [ , initialValue ] )

Note 1

callback should be a function that takes four arguments. reduceRight calls the callback, as a function, once for each element after the first element present in the array, in descending order.

callback is called with four arguments: the previousValue (value from the previous call to callback), the currentValue (value of the current element), the currentIndex, and the object being traversed. The first time the function is called, the previousValue and currentValue can be one of two values. If an initialValue was supplied in the call to reduceRight, then previousValue will be initialValue and currentValue will be the last value in the array. If no initialValue was supplied, then previousValue will be the last value in the array and currentValue will be the second-to-last value. It is a TypeError if the array contains no elements and initialValue is not provided.

reduceRight does not directly mutate the object on which it is called but the object may be mutated by the calls to callback.

The range of elements processed by reduceRight is set before the first call to callback. Elements that are appended to the array after the call to reduceRight begins will not be visited by callback. If existing elements of the array are changed by callback, their value as passed to callback will be the value at the time reduceRight visits them; elements that are deleted after the call to reduceRight begins and before being visited are not visited.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. If IsCallable(callback) is false, throw a TypeError exception.
  4. If len = 0 and initialValue is not present, throw a TypeError exception.
  5. Let k be len - 1.
  6. Let accumulator be undefined.
  7. If initialValue is present, then
    1. Set accumulator to initialValue.
  8. Else,
    1. Let kPresent be false.
    2. Repeat, while kPresent is false and k ≥ 0,
      1. Let Pk be ! ToString(𝔽(k)).
      2. Set kPresent to ? HasProperty(O, Pk).
      3. If kPresent is true, then
        1. Set accumulator to ? Get(O, Pk).
      4. Set k to k - 1.
    3. If kPresent is false, throw a TypeError exception.
  9. Repeat, while k ≥ 0,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kPresent be ? HasProperty(O, Pk).
    3. If kPresent is true, then
      1. Let kValue be ? Get(O, Pk).
      2. Set accumulator to ? Call(callback, undefined, « accumulator, kValue, 𝔽(k), O »).
    4. Set k to k - 1.
  10. Return accumulator.
Note 2

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.26 Array.prototype.reverse ( )

Note 1

This method rearranges the elements of the array so as to reverse their order. It returns the reversed array.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. Let middle be floor(len / 2).
  4. Let lower be 0.
  5. Repeat, while lowermiddle,
    1. Let upper be len - lower - 1.
    2. Let upperP be ! ToString(𝔽(upper)).
    3. Let lowerP be ! ToString(𝔽(lower)).
    4. Let lowerExists be ? HasProperty(O, lowerP).
    5. If lowerExists is true, then
      1. Let lowerValue be ? Get(O, lowerP).
    6. Let upperExists be ? HasProperty(O, upperP).
    7. If upperExists is true, then
      1. Let upperValue be ? Get(O, upperP).
    8. If lowerExists is true and upperExists is true, then
      1. Perform ? Set(O, lowerP, upperValue, true).
      2. Perform ? Set(O, upperP, lowerValue, true).
    9. Else if lowerExists is false and upperExists is true, then
      1. Perform ? Set(O, lowerP, upperValue, true).
      2. Perform ? DeletePropertyOrThrow(O, upperP).
    10. Else if lowerExists is true and upperExists is false, then
      1. Perform ? DeletePropertyOrThrow(O, lowerP).
      2. Perform ? Set(O, upperP, lowerValue, true).
    11. Else,
      1. Assert: lowerExists and upperExists are both false.
      2. NOTE: No action is required.
    12. Set lower to lower + 1.
  6. Return O.
Note 2

This method is intentionally generic; it does not require that its this value be an Array. Therefore, it can be transferred to other kinds of objects for use as a method.

23.1.3.27 Array.prototype.shift ( )

This method removes the first element of the array and returns it.

It performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. If len = 0, then
    1. Perform ? Set(O, "length", +0𝔽, true).
    2. Return undefined.
  4. Let first be ? Get(O, "0").
  5. Let k be 1.
  6. Repeat, while k < len,
    1. Let from be ! ToString(𝔽(k)).
    2. Let to be ! ToString(𝔽(k - 1)).
    3. Let fromPresent be ? HasProperty(O, from).
    4. If fromPresent is true, then
      1. Let fromValue be ? Get(O, from).
      2. Perform ? Set(O, to, fromValue, true).
    5. Else,
      1. Assert: fromPresent is false.
      2. Perform ? DeletePropertyOrThrow(O, to).
    6. Set k to k + 1.
  7. Perform ? DeletePropertyOrThrow(O, ! ToString(𝔽(len - 1))).
  8. Perform ? Set(O, "length", 𝔽(len - 1), true).
  9. Return first.
Note

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.28 Array.prototype.slice ( start, end )

This method returns an array containing the elements of the array from element start up to, but not including, element end (or through the end of the array if end is undefined). If start is negative, it is treated as length + start where length is the length of the array. If end is negative, it is treated as length + end where length is the length of the array.

It performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. Let relativeStart be ? ToIntegerOrInfinity(start).
  4. If relativeStart = -∞, let k be 0.
  5. Else if relativeStart < 0, let k be max(len + relativeStart, 0).
  6. Else, let k be min(relativeStart, len).
  7. If end is undefined, let relativeEnd be len; else let relativeEnd be ? ToIntegerOrInfinity(end).
  8. If relativeEnd = -∞, let final be 0.
  9. Else if relativeEnd < 0, let final be max(len + relativeEnd, 0).
  10. Else, let final be min(relativeEnd, len).
  11. Let count be max(final - k, 0).
  12. Let A be ? ArraySpeciesCreate(O, count).
  13. Let n be 0.
  14. Repeat, while k < final,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kPresent be ? HasProperty(O, Pk).
    3. If kPresent is true, then
      1. Let kValue be ? Get(O, Pk).
      2. Perform ? CreateDataPropertyOrThrow(A, ! ToString(𝔽(n)), kValue).
    4. Set k to k + 1.
    5. Set n to n + 1.
  15. Perform ? Set(A, "length", 𝔽(n), true).
  16. Return A.
Note 1

The explicit setting of the "length" property in step 15 is intended to ensure the length is correct even when A is not a built-in Array.

Note 2

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.29 Array.prototype.some ( callback [ , thisArg ] )

Note 1

callback should be a function that accepts three arguments and returns a value that is coercible to a Boolean value. some calls callback once for each element present in the array, in ascending order, until it finds one where callback returns true. If such an element is found, some immediately returns true. Otherwise, some returns false. callback is called only for elements of the array which actually exist; it is not called for missing elements of the array.

If a thisArg parameter is provided, it will be used as the this value for each invocation of callback. If it is not provided, undefined is used instead.

callback is called with three arguments: the value of the element, the index of the element, and the object being traversed.

some does not directly mutate the object on which it is called but the object may be mutated by the calls to callback.

The range of elements processed by some is set before the first call to callback. Elements that are appended to the array after the call to some begins will not be visited by callback. If existing elements of the array are changed, their value as passed to callback will be the value at the time that some visits them; elements that are deleted after the call to some begins and before being visited are not visited. some acts like the "exists" quantifier in mathematics. In particular, for an empty array, it returns false.

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. If IsCallable(callback) is false, throw a TypeError exception.
  4. Let k be 0.
  5. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kPresent be ? HasProperty(O, Pk).
    3. If kPresent is true, then
      1. Let kValue be ? Get(O, Pk).
      2. Let testResult be ToBoolean(? Call(callback, thisArg, « kValue, 𝔽(k), O »)).
      3. If testResult is true, return true.
    4. Set k to k + 1.
  6. Return false.
Note 2

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.30 Array.prototype.sort ( comparator )

This method sorts the elements of this array. If comparator is not undefined, it should be a function that accepts two arguments x and y and returns a negative Number if x < y, a positive Number if x > y, or a zero otherwise.

It performs the following steps when called:

  1. If comparator is not undefined and IsCallable(comparator) is false, throw a TypeError exception.
  2. Let obj be ? ToObject(this value).
  3. Let len be ? LengthOfArrayLike(obj).
  4. Let SortCompare be a new Abstract Closure with parameters (x, y) that captures comparator and performs the following steps when called:
    1. Return ? CompareArrayElements(x, y, comparator).
  5. Let sortedList be ? SortIndexedProperties(obj, len, SortCompare, skip-holes).
  6. Let itemCount be the number of elements in sortedList.
  7. Let j be 0.
  8. Repeat, while j < itemCount,
    1. Perform ? Set(obj, ! ToString(𝔽(j)), sortedList[j], true).
    2. Set j to j + 1.
  9. NOTE: The call to SortIndexedProperties in step 5 uses skip-holes. The remaining indices are deleted to preserve the number of holes that were detected and excluded from the sort.
  10. Repeat, while j < len,
    1. Perform ? DeletePropertyOrThrow(obj, ! ToString(𝔽(j))).
    2. Set j to j + 1.
  11. Return obj.
Note 1

Because non-existent property values always compare greater than undefined property values, and undefined always compares greater than any other value (see CompareArrayElements), undefined property values always sort to the end of the result, followed by non-existent property values.

Note 2

Method calls performed by the ToString abstract operations in steps 5 and 6 have the potential to cause SortCompare to not behave as a consistent comparator.

Note 3

This method is intentionally generic; it does not require that its this value be an Array. Therefore, it can be transferred to other kinds of objects for use as a method.

23.1.3.30.1 SortIndexedProperties ( obj, len, SortCompare, holes )

The abstract operation SortIndexedProperties takes arguments obj (an Object), len (a non-negative integer), SortCompare (an Abstract Closure with two parameters), and holes (skip-holes or read-through-holes) and returns either a normal completion containing a List of ECMAScript language values or a throw completion. It performs the following steps when called:

  1. Let items be a new empty List.
  2. Let k be 0.
  3. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. If holes is skip-holes, then
      1. Let kRead be ? HasProperty(obj, Pk).
    3. Else,
      1. Assert: holes is read-through-holes.
      2. Let kRead be true.
    4. If kRead is true, then
      1. Let kValue be ? Get(obj, Pk).
      2. Append kValue to items.
    5. Set k to k + 1.
  4. Sort items using an implementation-defined sequence of calls to SortCompare. If any such call returns an abrupt completion, stop before performing any further calls to SortCompare and return that Completion Record.
  5. Return items.

The sort order is the ordering of items after completion of step 4 of the algorithm above. The sort order is implementation-defined if SortCompare is not a consistent comparator for the elements of items. When SortIndexedProperties is invoked by Array.prototype.sort or Array.prototype.toSorted, the sort order is also implementation-defined if comparator is undefined, and all applications of ToString, to any specific value passed as an argument to SortCompare, do not produce the same result.

Unless the sort order is specified to be implementation-defined, it must satisfy all of the following conditions:

  • There must be some mathematical permutation π of the non-negative integers less than itemCount, such that for every non-negative integer j less than itemCount, the element old[j] is exactly the same as new[π(j)].
  • Then for all non-negative integers j and k, each less than itemCount, if (SortCompare(old[j], old[k])) < 0, then π(j) < π(k).
  • And for all non-negative integers j and k such that j < k < itemCount, if (SortCompare(old[j], old[k])) = 0, then π(j) < π(k); i.e., the sort is stable.

Here the notation old[j] is used to refer to items[j] before step 4 is executed, and the notation new[j] to refer to items[j] after step 4 has been executed.

An abstract closure or function comparator is a consistent comparator for a set of values S if all of the requirements below are met for all values a, b, and c (possibly the same value) in the set S: The notation a <C b means (comparator(a, b)) < 0; a =C b means (comparator(a, b)) = 0; and a >C b means (comparator(a, b)) > 0.

  • Calling comparator(a, b) always returns the same value v when given a specific pair of values a and b as its two arguments. Furthermore, v is a Number, and v is not NaN. Note that this implies that exactly one of a <C b, a =C b, and a >C b will be true for a given pair of a and b.
  • Calling comparator(a, b) does not modify obj or any object on obj's prototype chain.
  • a =C a (reflexivity)
  • If a =C b, then b =C a (symmetry)
  • If a =C b and b =C c, then a =C c (transitivity of =C)
  • If a <C b and b <C c, then a <C c (transitivity of <C)
  • If a >C b and b >C c, then a >C c (transitivity of >C)
Note

The above conditions are necessary and sufficient to ensure that comparator divides the set S into equivalence classes and that these equivalence classes are totally ordered.

23.1.3.30.2 CompareArrayElements ( x, y, comparator )

The abstract operation CompareArrayElements takes arguments x (an ECMAScript language value), y (an ECMAScript language value), and comparator (a function object or undefined) and returns either a normal completion containing a Number or an abrupt completion. It performs the following steps when called:

  1. If x and y are both undefined, return +0𝔽.
  2. If x is undefined, return 1𝔽.
  3. If y is undefined, return -1𝔽.
  4. If comparator is not undefined, then
    1. Let v be ? ToNumber(? Call(comparator, undefined, « x, y »)).
    2. If v is NaN, return +0𝔽.
    3. Return v.
  5. Let xString be ? ToString(x).
  6. Let yString be ? ToString(y).
  7. Let xSmaller be ! IsLessThan(xString, yString, true).
  8. If xSmaller is true, return -1𝔽.
  9. Let ySmaller be ! IsLessThan(yString, xString, true).
  10. If ySmaller is true, return 1𝔽.
  11. Return +0𝔽.

23.1.3.31 Array.prototype.splice ( start, deleteCount, ...items )

Note 1

This method deletes the deleteCount elements of the array starting at integer index start and replaces them with the elements of items. It returns an Array containing the deleted elements (if any).

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. Let relativeStart be ? ToIntegerOrInfinity(start).
  4. If relativeStart = -∞, let actualStart be 0.
  5. Else if relativeStart < 0, let actualStart be max(len + relativeStart, 0).
  6. Else, let actualStart be min(relativeStart, len).
  7. Let itemCount be the number of elements in items.
  8. If start is not present, then
    1. Let actualDeleteCount be 0.
  9. Else if deleteCount is not present, then
    1. Let actualDeleteCount be len - actualStart.
  10. Else,
    1. Let dc be ? ToIntegerOrInfinity(deleteCount).
    2. Let actualDeleteCount be the result of clamping dc between 0 and len - actualStart.
  11. If len + itemCount - actualDeleteCount > 253 - 1, throw a TypeError exception.
  12. Let A be ? ArraySpeciesCreate(O, actualDeleteCount).
  13. Let k be 0.
  14. Repeat, while k < actualDeleteCount,
    1. Let from be ! ToString(𝔽(actualStart + k)).
    2. If ? HasProperty(O, from) is true, then
      1. Let fromValue be ? Get(O, from).
      2. Perform ? CreateDataPropertyOrThrow(A, ! ToString(𝔽(k)), fromValue).
    3. Set k to k + 1.
  15. Perform ? Set(A, "length", 𝔽(actualDeleteCount), true).
  16. If itemCount < actualDeleteCount, then
    1. Set k to actualStart.
    2. Repeat, while k < (len - actualDeleteCount),
      1. Let from be ! ToString(𝔽(k + actualDeleteCount)).
      2. Let to be ! ToString(𝔽(k + itemCount)).
      3. If ? HasProperty(O, from) is true, then
        1. Let fromValue be ? Get(O, from).
        2. Perform ? Set(O, to, fromValue, true).
      4. Else,
        1. Perform ? DeletePropertyOrThrow(O, to).
      5. Set k to k + 1.
    3. Set k to len.
    4. Repeat, while k > (len - actualDeleteCount + itemCount),
      1. Perform ? DeletePropertyOrThrow(O, ! ToString(𝔽(k - 1))).
      2. Set k to k - 1.
  17. Else if itemCount > actualDeleteCount, then
    1. Set k to (len - actualDeleteCount).
    2. Repeat, while k > actualStart,
      1. Let from be ! ToString(𝔽(k + actualDeleteCount - 1)).
      2. Let to be ! ToString(𝔽(k + itemCount - 1)).
      3. If ? HasProperty(O, from) is true, then
        1. Let fromValue be ? Get(O, from).
        2. Perform ? Set(O, to, fromValue, true).
      4. Else,
        1. Perform ? DeletePropertyOrThrow(O, to).
      5. Set k to k - 1.
  18. Set k to actualStart.
  19. For each element E of items, do
    1. Perform ? Set(O, ! ToString(𝔽(k)), E, true).
    2. Set k to k + 1.
  20. Perform ? Set(O, "length", 𝔽(len - actualDeleteCount + itemCount), true).
  21. Return A.
Note 2

The explicit setting of the "length" property in steps 15 and 20 is intended to ensure the lengths are correct even when the objects are not built-in Arrays.

Note 3

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.32 Array.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] )

An ECMAScript implementation that includes the ECMA-402 Internationalization API must implement this method as specified in the ECMA-402 specification. If an ECMAScript implementation does not include the ECMA-402 API the following specification of this method is used.

Note 1

The first edition of ECMA-402 did not include a replacement specification for this method.

The meanings of the optional parameters to this method are defined in the ECMA-402 specification; implementations that do not include ECMA-402 support must not use those parameter positions for anything else.

This method performs the following steps when called:

  1. Let array be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(array).
  3. Let separator be the implementation-defined list-separator String value appropriate for the host environment's current locale (such as ", ").
  4. Let R be the empty String.
  5. Let k be 0.
  6. Repeat, while k < len,
    1. If k > 0, set R to the string-concatenation of R and separator.
    2. Let element be ? Get(array, ! ToString(𝔽(k))).
    3. If element is neither undefined nor null, then
      1. Let S be ? ToString(? Invoke(element, "toLocaleString")).
      2. Set R to the string-concatenation of R and S.
    4. Set k to k + 1.
  7. Return R.
Note 2

This method converts the elements of the array to Strings using their toLocaleString methods, and then concatenates these Strings, separated by occurrences of an implementation-defined locale-sensitive separator String. This method is analogous to toString except that it is intended to yield a locale-sensitive result corresponding with conventions of the host environment's current locale.

Note 3

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.33 Array.prototype.toReversed ( )

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. Let A be ? ArrayCreate(len).
  4. Let k be 0.
  5. Repeat, while k < len,
    1. Let from be ! ToString(𝔽(len - k - 1)).
    2. Let Pk be ! ToString(𝔽(k)).
    3. Let fromValue be ? Get(O, from).
    4. Perform ! CreateDataPropertyOrThrow(A, Pk, fromValue).
    5. Set k to k + 1.
  6. Return A.

23.1.3.34 Array.prototype.toSorted ( comparator )

This method performs the following steps when called:

  1. If comparator is not undefined and IsCallable(comparator) is false, throw a TypeError exception.
  2. Let O be ? ToObject(this value).
  3. Let len be ? LengthOfArrayLike(O).
  4. Let A be ? ArrayCreate(len).
  5. Let SortCompare be a new Abstract Closure with parameters (x, y) that captures comparator and performs the following steps when called:
    1. Return ? CompareArrayElements(x, y, comparator).
  6. Let sortedList be ? SortIndexedProperties(O, len, SortCompare, read-through-holes).
  7. Let j be 0.
  8. Repeat, while j < len,
    1. Perform ! CreateDataPropertyOrThrow(A, ! ToString(𝔽(j)), sortedList[j]).
    2. Set j to j + 1.
  9. Return A.

23.1.3.35 Array.prototype.toSpliced ( start, skipCount, ...items )

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. Let relativeStart be ? ToIntegerOrInfinity(start).
  4. If relativeStart = -∞, let actualStart be 0.
  5. Else if relativeStart < 0, let actualStart be max(len + relativeStart, 0).
  6. Else, let actualStart be min(relativeStart, len).
  7. Let insertCount be the number of elements in items.
  8. If start is not present, then
    1. Let actualSkipCount be 0.
  9. Else if skipCount is not present, then
    1. Let actualSkipCount be len - actualStart.
  10. Else,
    1. Let sc be ? ToIntegerOrInfinity(skipCount).
    2. Let actualSkipCount be the result of clamping sc between 0 and len - actualStart.
  11. Let newLen be len + insertCount - actualSkipCount.
  12. If newLen > 253 - 1, throw a TypeError exception.
  13. Let A be ? ArrayCreate(newLen).
  14. Let i be 0.
  15. Let r be actualStart + actualSkipCount.
  16. Repeat, while i < actualStart,
    1. Let Pi be ! ToString(𝔽(i)).
    2. Let iValue be ? Get(O, Pi).
    3. Perform ! CreateDataPropertyOrThrow(A, Pi, iValue).
    4. Set i to i + 1.
  17. For each element E of items, do
    1. Let Pi be ! ToString(𝔽(i)).
    2. Perform ! CreateDataPropertyOrThrow(A, Pi, E).
    3. Set i to i + 1.
  18. Repeat, while i < newLen,
    1. Let Pi be ! ToString(𝔽(i)).
    2. Let from be ! ToString(𝔽(r)).
    3. Let fromValue be ? Get(O, from).
    4. Perform ! CreateDataPropertyOrThrow(A, Pi, fromValue).
    5. Set i to i + 1.
    6. Set r to r + 1.
  19. Return A.

23.1.3.36 Array.prototype.toString ( )

This method performs the following steps when called:

  1. Let array be ? ToObject(this value).
  2. Let func be ? Get(array, "join").
  3. If IsCallable(func) is false, set func to the intrinsic function %Object.prototype.toString%.
  4. Return ? Call(func, array).
Note

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.37 Array.prototype.unshift ( ...items )

This method prepends the arguments to the start of the array, such that their order within the array is the same as the order in which they appear in the argument list.

It performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. Let argCount be the number of elements in items.
  4. If argCount > 0, then
    1. If len + argCount > 253 - 1, throw a TypeError exception.
    2. Let k be len.
    3. Repeat, while k > 0,
      1. Let from be ! ToString(𝔽(k - 1)).
      2. Let to be ! ToString(𝔽(k + argCount - 1)).
      3. Let fromPresent be ? HasProperty(O, from).
      4. If fromPresent is true, then
        1. Let fromValue be ? Get(O, from).
        2. Perform ? Set(O, to, fromValue, true).
      5. Else,
        1. Assert: fromPresent is false.
        2. Perform ? DeletePropertyOrThrow(O, to).
      6. Set k to k - 1.
    4. Let j be +0𝔽.
    5. For each element E of items, do
      1. Perform ? Set(O, ! ToString(j), E, true).
      2. Set j to j + 1𝔽.
  5. Perform ? Set(O, "length", 𝔽(len + argCount), true).
  6. Return 𝔽(len + argCount).

The "length" property of this method is 1𝔽.

Note

This method is intentionally generic; it does not require that its this value be an Array. Therefore it can be transferred to other kinds of objects for use as a method.

23.1.3.38 Array.prototype.values ( )

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Return CreateArrayIterator(O, value).

23.1.3.39 Array.prototype.with ( index, value )

This method performs the following steps when called:

  1. Let O be ? ToObject(this value).
  2. Let len be ? LengthOfArrayLike(O).
  3. Let relativeIndex be ? ToIntegerOrInfinity(index).
  4. If relativeIndex ≥ 0, let actualIndex be relativeIndex.
  5. Else, let actualIndex be len + relativeIndex.
  6. If actualIndexlen or actualIndex < 0, throw a RangeError exception.
  7. Let A be ? ArrayCreate(len).
  8. Let k be 0.
  9. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. If k = actualIndex, let fromValue be value.
    3. Else, let fromValue be ? Get(O, Pk).
    4. Perform ! CreateDataPropertyOrThrow(A, Pk, fromValue).
    5. Set k to k + 1.
  10. Return A.

23.1.3.40 Array.prototype [ %Symbol.iterator% ] ( )

The initial value of the %Symbol.iterator% property is %Array.prototype.values%, defined in 23.1.3.38.

23.1.3.41 Array.prototype [ %Symbol.unscopables% ]

The initial value of the %Symbol.unscopables% data property is an object created by the following steps:

  1. Let unscopableList be OrdinaryObjectCreate(null).
  2. Perform ! CreateDataPropertyOrThrow(unscopableList, "at", true).
  3. Perform ! CreateDataPropertyOrThrow(unscopableList, "copyWithin", true).
  4. Perform ! CreateDataPropertyOrThrow(unscopableList, "entries", true).
  5. Perform ! CreateDataPropertyOrThrow(unscopableList, "fill", true).
  6. Perform ! CreateDataPropertyOrThrow(unscopableList, "find", true).
  7. Perform ! CreateDataPropertyOrThrow(unscopableList, "findIndex", true).
  8. Perform ! CreateDataPropertyOrThrow(unscopableList, "findLast", true).
  9. Perform ! CreateDataPropertyOrThrow(unscopableList, "findLastIndex", true).
  10. Perform ! CreateDataPropertyOrThrow(unscopableList, "flat", true).
  11. Perform ! CreateDataPropertyOrThrow(unscopableList, "flatMap", true).
  12. Perform ! CreateDataPropertyOrThrow(unscopableList, "includes", true).
  13. Perform ! CreateDataPropertyOrThrow(unscopableList, "keys", true).
  14. Perform ! CreateDataPropertyOrThrow(unscopableList, "toReversed", true).
  15. Perform ! CreateDataPropertyOrThrow(unscopableList, "toSorted", true).
  16. Perform ! CreateDataPropertyOrThrow(unscopableList, "toSpliced", true).
  17. Perform ! CreateDataPropertyOrThrow(unscopableList, "values", true).
  18. Return unscopableList.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

Note

The own property names of this object are property names that were not included as standard properties of Array.prototype prior to the ECMAScript 2015 specification. These names are ignored for with statement binding purposes in order to preserve the behaviour of existing code that might use one of these names as a binding in an outer scope that is shadowed by a with statement whose binding object is an Array.

The reason that "with" is not included in the unscopableList is because it is already a reserved word.

23.1.4 Properties of Array Instances

Array instances are Array exotic objects and have the internal methods specified for such objects. Array instances inherit properties from the Array prototype object.

Array instances have a "length" property, and a set of enumerable properties with array index names.

23.1.4.1 length

The "length" property of an Array instance is a data property whose value is always numerically greater than the name of every configurable own property whose name is an array index.

The "length" property initially has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }.

Note

Reducing the value of the "length" property has the side-effect of deleting own array elements whose array index is between the old and new length values. However, non-configurable properties can not be deleted. Attempting to set the "length" property of an Array to a value that is numerically less than or equal to the largest numeric own property name of an existing non-configurable array-indexed property of the array will result in the length being set to a numeric value that is one greater than that non-configurable numeric own property name. See 10.4.2.1.

23.1.5 Array Iterator Objects

An Array Iterator is an object that represents a specific iteration over some specific Array instance object. There is not a named constructor for Array Iterator objects. Instead, Array Iterator objects are created by calling certain methods of Array instance objects.

23.1.5.1 CreateArrayIterator ( array, kind )

The abstract operation CreateArrayIterator takes arguments array (an Object) and kind (key+value, key, or value) and returns an Object. It is used to create iterator objects for Array methods that return such iterators. It performs the following steps when called:

  1. Let iterator be OrdinaryObjectCreate(%ArrayIteratorPrototype%, « [[IteratedArrayLike]], [[ArrayLikeNextIndex]], [[ArrayLikeIterationKind]] »).
  2. Set iterator.[[IteratedArrayLike]] to array.
  3. Set iterator.[[ArrayLikeNextIndex]] to 0.
  4. Set iterator.[[ArrayLikeIterationKind]] to kind.
  5. Return iterator.

23.1.5.2 The %ArrayIteratorPrototype% Object

The %ArrayIteratorPrototype% object:

23.1.5.2.1 %ArrayIteratorPrototype%.next ( )

  1. Let O be the this value.
  2. If O is not an Object, throw a TypeError exception.
  3. If O does not have all of the internal slots of an Array Iterator Instance (23.1.5.3), throw a TypeError exception.
  4. Let array be O.[[IteratedArrayLike]].
  5. If array is undefined, return CreateIteratorResultObject(undefined, true).
  6. Let index be O.[[ArrayLikeNextIndex]].
  7. Let kind be O.[[ArrayLikeIterationKind]].
  8. If array has a [[TypedArrayName]] internal slot, then
    1. Let taRecord be MakeTypedArrayWithBufferWitnessRecord(array, seq-cst).
    2. If IsTypedArrayOutOfBounds(taRecord) is true, throw a TypeError exception.
    3. Let len be TypedArrayLength(taRecord).
  9. Else,
    1. Let len be ? LengthOfArrayLike(array).
  10. If indexlen, then
    1. Set O.[[IteratedArrayLike]] to undefined.
    2. Return CreateIteratorResultObject(undefined, true).
  11. Set O.[[ArrayLikeNextIndex]] to index + 1.
  12. Let indexNumber be 𝔽(index).
  13. If kind is key, then
    1. Let result be indexNumber.
  14. Else,
    1. Let elementKey be ! ToString(indexNumber).
    2. Let elementValue be ? Get(array, elementKey).
    3. If kind is value, then
      1. Let result be elementValue.
    4. Else,
      1. Assert: kind is key+value.
      2. Let result be CreateArrayFromListindexNumber, elementValue »).
  15. Return CreateIteratorResultObject(result, false).

23.1.5.2.2 %ArrayIteratorPrototype% [ %Symbol.toStringTag% ]

The initial value of the %Symbol.toStringTag% property is the String value "Array Iterator".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

23.1.5.3 Properties of Array Iterator Instances

Array Iterator instances are ordinary objects that inherit properties from the %ArrayIteratorPrototype% intrinsic object. Array Iterator instances are initially created with the internal slots listed in Table 74.

Table 74: Internal Slots of Array Iterator Instances
Internal Slot Type Description
[[IteratedArrayLike]] an Object or undefined The array-like object that is being iterated.
[[ArrayLikeNextIndex]] a non-negative integer The integer index of the next element to be examined by this iterator.
[[ArrayLikeIterationKind]] key+value, key, or value A value that identifies what is returned for each element of the iteration.

23.2 TypedArray Objects

A TypedArray presents an array-like view of an underlying binary data buffer (25.1). A TypedArray element type is the underlying binary scalar data type that all elements of a TypedArray instance have. There is a distinct TypedArray constructor, listed in Table 75, for each of the supported element types. Each constructor in Table 75 has a corresponding distinct prototype object.

Table 75: The TypedArray Constructors
Constructor Name and Intrinsic Element Type Element Size Conversion Operation Description
Int8Array
%Int8Array%
int8 1 ToInt8 8-bit two's complement signed integer
Uint8Array
%Uint8Array%
uint8 1 ToUint8 8-bit unsigned integer
Uint8ClampedArray
%Uint8ClampedArray%
uint8clamped 1 ToUint8Clamp 8-bit unsigned integer (clamped conversion)
Int16Array
%Int16Array%
int16 2 ToInt16 16-bit two's complement signed integer
Uint16Array
%Uint16Array%
uint16 2 ToUint16 16-bit unsigned integer
Int32Array
%Int32Array%
int32 4 ToInt32 32-bit two's complement signed integer
Uint32Array
%Uint32Array%
uint32 4 ToUint32 32-bit unsigned integer
BigInt64Array
%BigInt64Array%
bigint64 8 ToBigInt64 64-bit two's complement signed integer
BigUint64Array
%BigUint64Array%
biguint64 8 ToBigUint64 64-bit unsigned integer
Float16Array
%Float16Array%
float16 2 16-bit IEEE floating point
Float32Array
%Float32Array%
float32 4 32-bit IEEE floating point
Float64Array
%Float64Array%
float64 8 64-bit IEEE floating point

In the definitions below, references to TypedArray should be replaced with the appropriate constructor name from the above table.

23.2.1 The %TypedArray% Intrinsic Object

The %TypedArray% intrinsic object:

  • is a constructor function object that all of the TypedArray constructor objects inherit from.
  • along with its corresponding prototype object, provides common properties that are inherited by all TypedArray constructors and their instances.
  • does not have a global name or appear as a property of the global object.
  • acts as the abstract superclass of the various TypedArray constructors.
  • will throw an error when invoked, because it is an abstract class constructor. The TypedArray constructors do not perform a super call to it.

23.2.1.1 %TypedArray% ( )

This function performs the following steps when called:

  1. Throw a TypeError exception.

The "length" property of this function is +0𝔽.

23.2.2 Properties of the %TypedArray% Intrinsic Object

The %TypedArray% intrinsic object:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has a "name" property whose value is "TypedArray".
  • has the following properties:

23.2.2.1 %TypedArray%.from ( source [ , mapper [ , thisArg ] ] )

This method performs the following steps when called:

  1. Let C be the this value.
  2. If IsConstructor(C) is false, throw a TypeError exception.
  3. If mapper is undefined, then
    1. Let mapping be false.
  4. Else,
    1. If IsCallable(mapper) is false, throw a TypeError exception.
    2. Let mapping be true.
  5. Let usingIterator be ? GetMethod(source, %Symbol.iterator%).
  6. If usingIterator is not undefined, then
    1. Let values be ? IteratorToList(? GetIteratorFromMethod(source, usingIterator)).
    2. Let len be the number of elements in values.
    3. Let targetObj be ? TypedArrayCreateFromConstructor(C, « 𝔽(len) »).
    4. Let k be 0.
    5. Repeat, while k < len,
      1. Let Pk be ! ToString(𝔽(k)).
      2. Let kValue be the first element of values.
      3. Remove the first element from values.
      4. If mapping is true, then
        1. Let mappedValue be ? Call(mapper, thisArg, « kValue, 𝔽(k) »).
      5. Else,
        1. Let mappedValue be kValue.
      6. Perform ? Set(targetObj, Pk, mappedValue, true).
      7. Set k to k + 1.
    6. Assert: values is now an empty List.
    7. Return targetObj.
  7. NOTE: source is not an iterable object, so assume it is already an array-like object.
  8. Let arrayLike be ! ToObject(source).
  9. Let len be ? LengthOfArrayLike(arrayLike).
  10. Let targetObj be ? TypedArrayCreateFromConstructor(C, « 𝔽(len) »).
  11. Let k be 0.
  12. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kValue be ? Get(arrayLike, Pk).
    3. If mapping is true, then
      1. Let mappedValue be ? Call(mapper, thisArg, « kValue, 𝔽(k) »).
    4. Else,
      1. Let mappedValue be kValue.
    5. Perform ? Set(targetObj, Pk, mappedValue, true).
    6. Set k to k + 1.
  13. Return targetObj.

23.2.2.2 %TypedArray%.of ( ...items )

This method performs the following steps when called:

  1. Let len be the number of elements in items.
  2. Let C be the this value.
  3. If IsConstructor(C) is false, throw a TypeError exception.
  4. Let newObj be ? TypedArrayCreateFromConstructor(C, « 𝔽(len) »).
  5. Let k be 0.
  6. Repeat, while k < len,
    1. Let kValue be items[k].
    2. Let Pk be ! ToString(𝔽(k)).
    3. Perform ? Set(newObj, Pk, kValue, true).
    4. Set k to k + 1.
  7. Return newObj.

23.2.2.3 %TypedArray%.prototype

The initial value of %TypedArray%.prototype is the %TypedArray% prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

23.2.2.4 get %TypedArray% [ %Symbol.species% ]

%TypedArray%[%Symbol.species%] is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Return the this value.

The value of the "name" property of this function is "get [Symbol.species]".

Note

%TypedArray.prototype% methods normally use their this value's constructor to create a derived object. However, a subclass constructor may over-ride that default behaviour by redefining its %Symbol.species% property.

23.2.3 Properties of the %TypedArray% Prototype Object

The %TypedArray% prototype object:

  • has a [[Prototype]] internal slot whose value is %Object.prototype%.
  • is %TypedArray.prototype%.
  • is an ordinary object.
  • does not have a [[ViewedArrayBuffer]] or any other of the internal slots that are specific to TypedArray instance objects.

23.2.3.1 %TypedArray%.prototype.at ( index )

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. Let relativeIndex be ? ToIntegerOrInfinity(index).
  5. If relativeIndex ≥ 0, then
    1. Let k be relativeIndex.
  6. Else,
    1. Let k be len + relativeIndex.
  7. If k < 0 or klen, return undefined.
  8. Return ! Get(O, ! ToString(𝔽(k))).

23.2.3.2 get %TypedArray%.prototype.buffer

%TypedArray%.prototype.buffer is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[TypedArrayName]]).
  3. Assert: O has a [[ViewedArrayBuffer]] internal slot.
  4. Let buffer be O.[[ViewedArrayBuffer]].
  5. Return buffer.

23.2.3.3 get %TypedArray%.prototype.byteLength

%TypedArray%.prototype.byteLength is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[TypedArrayName]]).
  3. Assert: O has a [[ViewedArrayBuffer]] internal slot.
  4. Let taRecord be MakeTypedArrayWithBufferWitnessRecord(O, seq-cst).
  5. Let size be TypedArrayByteLength(taRecord).
  6. Return 𝔽(size).

23.2.3.4 get %TypedArray%.prototype.byteOffset

%TypedArray%.prototype.byteOffset is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[TypedArrayName]]).
  3. Assert: O has a [[ViewedArrayBuffer]] internal slot.
  4. Let taRecord be MakeTypedArrayWithBufferWitnessRecord(O, seq-cst).
  5. If IsTypedArrayOutOfBounds(taRecord) is true, return +0𝔽.
  6. Let offset be O.[[ByteOffset]].
  7. Return 𝔽(offset).

23.2.3.5 %TypedArray%.prototype.constructor

The initial value of %TypedArray%.prototype.constructor is %TypedArray%.

23.2.3.6 %TypedArray%.prototype.copyWithin ( target, start [ , end ] )

The interpretation and use of the arguments of this method are the same as for Array.prototype.copyWithin as defined in 23.1.3.4.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. Let relativeTarget be ? ToIntegerOrInfinity(target).
  5. If relativeTarget = -∞, let targetIndex be 0.
  6. Else if relativeTarget < 0, let targetIndex be max(len + relativeTarget, 0).
  7. Else, let targetIndex be min(relativeTarget, len).
  8. Let relativeStart be ? ToIntegerOrInfinity(start).
  9. If relativeStart = -∞, let startIndex be 0.
  10. Else if relativeStart < 0, let startIndex be max(len + relativeStart, 0).
  11. Else, let startIndex be min(relativeStart, len).
  12. If end is undefined, let relativeEnd be len; else let relativeEnd be ? ToIntegerOrInfinity(end).
  13. If relativeEnd = -∞, let endIndex be 0.
  14. Else if relativeEnd < 0, let endIndex be max(len + relativeEnd, 0).
  15. Else, let endIndex be min(relativeEnd, len).
  16. Let count be min(endIndex - startIndex, len - targetIndex).
  17. If count > 0, then
    1. NOTE: The copying must be performed in a manner that preserves the bit-level encoding of the source data.
    2. Let buffer be O.[[ViewedArrayBuffer]].
    3. Set taRecord to MakeTypedArrayWithBufferWitnessRecord(O, seq-cst).
    4. If IsTypedArrayOutOfBounds(taRecord) is true, throw a TypeError exception.
    5. Set len to TypedArrayLength(taRecord).
    6. Let elementSize be TypedArrayElementSize(O).
    7. Let byteOffset be O.[[ByteOffset]].
    8. Let bufferByteLimit be (len × elementSize) + byteOffset.
    9. Let toByteIndex be (targetIndex × elementSize) + byteOffset.
    10. Let fromByteIndex be (startIndex × elementSize) + byteOffset.
    11. Let countBytes be count × elementSize.
    12. If fromByteIndex < toByteIndex and toByteIndex < fromByteIndex + countBytes, then
      1. Let direction be -1.
      2. Set fromByteIndex to fromByteIndex + countBytes - 1.
      3. Set toByteIndex to toByteIndex + countBytes - 1.
    13. Else,
      1. Let direction be 1.
    14. Repeat, while countBytes > 0,
      1. If fromByteIndex < bufferByteLimit and toByteIndex < bufferByteLimit, then
        1. Let value be GetValueFromBuffer(buffer, fromByteIndex, uint8, true, unordered).
        2. Perform SetValueInBuffer(buffer, toByteIndex, uint8, value, true, unordered).
        3. Set fromByteIndex to fromByteIndex + direction.
        4. Set toByteIndex to toByteIndex + direction.
        5. Set countBytes to countBytes - 1.
      2. Else,
        1. Set countBytes to 0.
  18. Return O.

23.2.3.7 %TypedArray%.prototype.entries ( )

This method performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? ValidateTypedArray(O, seq-cst).
  3. Return CreateArrayIterator(O, key+value).

23.2.3.8 %TypedArray%.prototype.every ( callback [ , thisArg ] )

The interpretation and use of the arguments of this method are the same as for Array.prototype.every as defined in 23.1.3.6.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. If IsCallable(callback) is false, throw a TypeError exception.
  5. Let k be 0.
  6. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kValue be ! Get(O, Pk).
    3. Let testResult be ToBoolean(? Call(callback, thisArg, « kValue, 𝔽(k), O »)).
    4. If testResult is false, return false.
    5. Set k to k + 1.
  7. Return true.

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.9 %TypedArray%.prototype.fill ( value [ , start [ , end ] ] )

The interpretation and use of the arguments of this method are the same as for Array.prototype.fill as defined in 23.1.3.7.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. If O.[[ContentType]] is bigint, set value to ? ToBigInt(value).
  5. Otherwise, set value to ? ToNumber(value).
  6. Let relativeStart be ? ToIntegerOrInfinity(start).
  7. If relativeStart = -∞, let startIndex be 0.
  8. Else if relativeStart < 0, let startIndex be max(len + relativeStart, 0).
  9. Else, let startIndex be min(relativeStart, len).
  10. If end is undefined, let relativeEnd be len; else let relativeEnd be ? ToIntegerOrInfinity(end).
  11. If relativeEnd = -∞, let endIndex be 0.
  12. Else if relativeEnd < 0, let endIndex be max(len + relativeEnd, 0).
  13. Else, let endIndex be min(relativeEnd, len).
  14. Set taRecord to MakeTypedArrayWithBufferWitnessRecord(O, seq-cst).
  15. If IsTypedArrayOutOfBounds(taRecord) is true, throw a TypeError exception.
  16. Set len to TypedArrayLength(taRecord).
  17. Set endIndex to min(endIndex, len).
  18. Let k be startIndex.
  19. Repeat, while k < endIndex,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Perform ! Set(O, Pk, value, true).
    3. Set k to k + 1.
  20. Return O.

23.2.3.10 %TypedArray%.prototype.filter ( callback [ , thisArg ] )

The interpretation and use of the arguments of this method are the same as for Array.prototype.filter as defined in 23.1.3.8.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. If IsCallable(callback) is false, throw a TypeError exception.
  5. Let kept be a new empty List.
  6. Let captured be 0.
  7. Let k be 0.
  8. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kValue be ! Get(O, Pk).
    3. Let selected be ToBoolean(? Call(callback, thisArg, « kValue, 𝔽(k), O »)).
    4. If selected is true, then
      1. Append kValue to kept.
      2. Set captured to captured + 1.
    5. Set k to k + 1.
  9. Let A be ? TypedArraySpeciesCreate(O, « 𝔽(captured) »).
  10. Let n be 0.
  11. For each element e of kept, do
    1. Perform ! Set(A, ! ToString(𝔽(n)), e, true).
    2. Set n to n + 1.
  12. Return A.

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.11 %TypedArray%.prototype.find ( predicate [ , thisArg ] )

The interpretation and use of the arguments of this method are the same as for Array.prototype.find as defined in 23.1.3.9.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. Let findRec be ? FindViaPredicate(O, len, ascending, predicate, thisArg).
  5. Return findRec.[[Value]].

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.12 %TypedArray%.prototype.findIndex ( predicate [ , thisArg ] )

The interpretation and use of the arguments of this method are the same as for Array.prototype.findIndex as defined in 23.1.3.10.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. Let findRec be ? FindViaPredicate(O, len, ascending, predicate, thisArg).
  5. Return findRec.[[Index]].

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.13 %TypedArray%.prototype.findLast ( predicate [ , thisArg ] )

The interpretation and use of the arguments of this method are the same as for Array.prototype.findLast as defined in 23.1.3.11.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. Let findRec be ? FindViaPredicate(O, len, descending, predicate, thisArg).
  5. Return findRec.[[Value]].

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.14 %TypedArray%.prototype.findLastIndex ( predicate [ , thisArg ] )

The interpretation and use of the arguments of this method are the same as for Array.prototype.findLastIndex as defined in 23.1.3.12.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. Let findRec be ? FindViaPredicate(O, len, descending, predicate, thisArg).
  5. Return findRec.[[Index]].

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.15 %TypedArray%.prototype.forEach ( callback [ , thisArg ] )

The interpretation and use of the arguments of this method are the same as for Array.prototype.forEach as defined in 23.1.3.15.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. If IsCallable(callback) is false, throw a TypeError exception.
  5. Let k be 0.
  6. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kValue be ! Get(O, Pk).
    3. Perform ? Call(callback, thisArg, « kValue, 𝔽(k), O »).
    4. Set k to k + 1.
  7. Return undefined.

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.16 %TypedArray%.prototype.includes ( searchElement [ , fromIndex ] )

The interpretation and use of the arguments of this method are the same as for Array.prototype.includes as defined in 23.1.3.16.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. If len = 0, return false.
  5. Let n be ? ToIntegerOrInfinity(fromIndex).
  6. Assert: If fromIndex is undefined, then n is 0.
  7. If n = +∞, return false.
  8. Else if n = -∞, set n to 0.
  9. If n ≥ 0, then
    1. Let k be n.
  10. Else,
    1. Let k be len + n.
    2. If k < 0, set k to 0.
  11. Repeat, while k < len,
    1. Let elementK be ! Get(O, ! ToString(𝔽(k))).
    2. If SameValueZero(searchElement, elementK) is true, return true.
    3. Set k to k + 1.
  12. Return false.

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.17 %TypedArray%.prototype.indexOf ( searchElement [ , fromIndex ] )

The interpretation and use of the arguments of this method are the same as for Array.prototype.indexOf as defined in 23.1.3.17.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. If len = 0, return -1𝔽.
  5. Let n be ? ToIntegerOrInfinity(fromIndex).
  6. Assert: If fromIndex is undefined, then n is 0.
  7. If n = +∞, return -1𝔽.
  8. Else if n = -∞, set n to 0.
  9. If n ≥ 0, then
    1. Let k be n.
  10. Else,
    1. Let k be len + n.
    2. If k < 0, set k to 0.
  11. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kPresent be ! HasProperty(O, Pk).
    3. If kPresent is true, then
      1. Let elementK be ! Get(O, Pk).
      2. If IsStrictlyEqual(searchElement, elementK) is true, return 𝔽(k).
    4. Set k to k + 1.
  12. Return -1𝔽.

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.18 %TypedArray%.prototype.join ( separator )

The interpretation and use of the arguments of this method are the same as for Array.prototype.join as defined in 23.1.3.18.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. If separator is undefined, let sep be ",".
  5. Else, let sep be ? ToString(separator).
  6. Let R be the empty String.
  7. Let k be 0.
  8. Repeat, while k < len,
    1. If k > 0, set R to the string-concatenation of R and sep.
    2. Let element be ! Get(O, ! ToString(𝔽(k))).
    3. If element is not undefined, then
      1. Let S be ! ToString(element).
      2. Set R to the string-concatenation of R and S.
    4. Set k to k + 1.
  9. Return R.

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.19 %TypedArray%.prototype.keys ( )

This method performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? ValidateTypedArray(O, seq-cst).
  3. Return CreateArrayIterator(O, key).

23.2.3.20 %TypedArray%.prototype.lastIndexOf ( searchElement [ , fromIndex ] )

The interpretation and use of the arguments of this method are the same as for Array.prototype.lastIndexOf as defined in 23.1.3.20.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. If len = 0, return -1𝔽.
  5. If fromIndex is present, let n be ? ToIntegerOrInfinity(fromIndex); else let n be len - 1.
  6. If n = -∞, return -1𝔽.
  7. If n ≥ 0, then
    1. Let k be min(n, len - 1).
  8. Else,
    1. Let k be len + n.
  9. Repeat, while k ≥ 0,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kPresent be ! HasProperty(O, Pk).
    3. If kPresent is true, then
      1. Let elementK be ! Get(O, Pk).
      2. If IsStrictlyEqual(searchElement, elementK) is true, return 𝔽(k).
    4. Set k to k - 1.
  10. Return -1𝔽.

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.21 get %TypedArray%.prototype.length

%TypedArray%.prototype.length is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[TypedArrayName]]).
  3. Assert: O has [[ViewedArrayBuffer]] and [[ArrayLength]] internal slots.
  4. Let taRecord be MakeTypedArrayWithBufferWitnessRecord(O, seq-cst).
  5. If IsTypedArrayOutOfBounds(taRecord) is true, return +0𝔽.
  6. Let length be TypedArrayLength(taRecord).
  7. Return 𝔽(length).

This function is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.22 %TypedArray%.prototype.map ( callback [ , thisArg ] )

The interpretation and use of the arguments of this method are the same as for Array.prototype.map as defined in 23.1.3.21.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. If IsCallable(callback) is false, throw a TypeError exception.
  5. Let A be ? TypedArraySpeciesCreate(O, « 𝔽(len) »).
  6. Let k be 0.
  7. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kValue be ! Get(O, Pk).
    3. Let mappedValue be ? Call(callback, thisArg, « kValue, 𝔽(k), O »).
    4. Perform ? Set(A, Pk, mappedValue, true).
    5. Set k to k + 1.
  8. Return A.

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.23 %TypedArray%.prototype.reduce ( callback [ , initialValue ] )

The interpretation and use of the arguments of this method are the same as for Array.prototype.reduce as defined in 23.1.3.24.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. If IsCallable(callback) is false, throw a TypeError exception.
  5. If len = 0 and initialValue is not present, throw a TypeError exception.
  6. Let k be 0.
  7. Let accumulator be undefined.
  8. If initialValue is present, then
    1. Set accumulator to initialValue.
  9. Else,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Set accumulator to ! Get(O, Pk).
    3. Set k to k + 1.
  10. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kValue be ! Get(O, Pk).
    3. Set accumulator to ? Call(callback, undefined, « accumulator, kValue, 𝔽(k), O »).
    4. Set k to k + 1.
  11. Return accumulator.

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.24 %TypedArray%.prototype.reduceRight ( callback [ , initialValue ] )

The interpretation and use of the arguments of this method are the same as for Array.prototype.reduceRight as defined in 23.1.3.25.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. If IsCallable(callback) is false, throw a TypeError exception.
  5. If len = 0 and initialValue is not present, throw a TypeError exception.
  6. Let k be len - 1.
  7. Let accumulator be undefined.
  8. If initialValue is present, then
    1. Set accumulator to initialValue.
  9. Else,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Set accumulator to ! Get(O, Pk).
    3. Set k to k - 1.
  10. Repeat, while k ≥ 0,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kValue be ! Get(O, Pk).
    3. Set accumulator to ? Call(callback, undefined, « accumulator, kValue, 𝔽(k), O »).
    4. Set k to k - 1.
  11. Return accumulator.

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.25 %TypedArray%.prototype.reverse ( )

The interpretation and use of the arguments of this method are the same as for Array.prototype.reverse as defined in 23.1.3.26.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. Let middle be floor(len / 2).
  5. Let lower be 0.
  6. Repeat, while lowermiddle,
    1. Let upper be len - lower - 1.
    2. Let upperP be ! ToString(𝔽(upper)).
    3. Let lowerP be ! ToString(𝔽(lower)).
    4. Let lowerValue be ! Get(O, lowerP).
    5. Let upperValue be ! Get(O, upperP).
    6. Perform ! Set(O, lowerP, upperValue, true).
    7. Perform ! Set(O, upperP, lowerValue, true).
    8. Set lower to lower + 1.
  7. Return O.

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.26 %TypedArray%.prototype.set ( source [ , offset ] )

This method sets multiple values in this TypedArray, reading the values from source. The details differ based upon the type of source. The optional offset value indicates the first element index in this TypedArray where values are written. If omitted, it is assumed to be 0.

It performs the following steps when called:

  1. Let target be the this value.
  2. Perform ? RequireInternalSlot(target, [[TypedArrayName]]).
  3. Assert: target has a [[ViewedArrayBuffer]] internal slot.
  4. Let targetOffset be ? ToIntegerOrInfinity(offset).
  5. If targetOffset < 0, throw a RangeError exception.
  6. If source is an Object that has a [[TypedArrayName]] internal slot, then
    1. Perform ? SetTypedArrayFromTypedArray(target, targetOffset, source).
  7. Else,
    1. Perform ? SetTypedArrayFromArrayLike(target, targetOffset, source).
  8. Return undefined.

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.26.1 SetTypedArrayFromArrayLike ( target, targetOffset, source )

The abstract operation SetTypedArrayFromArrayLike takes arguments target (a TypedArray), targetOffset (a non-negative integer or +∞), and source (an ECMAScript language value, but not a TypedArray) and returns either a normal completion containing unused or a throw completion. It sets multiple values in target, starting at index targetOffset, reading the values from source. It performs the following steps when called:

  1. Let targetRecord be MakeTypedArrayWithBufferWitnessRecord(target, seq-cst).
  2. If IsTypedArrayOutOfBounds(targetRecord) is true, throw a TypeError exception.
  3. Let targetLength be TypedArrayLength(targetRecord).
  4. Let src be ? ToObject(source).
  5. Let srcLength be ? LengthOfArrayLike(src).
  6. If targetOffset = +∞, throw a RangeError exception.
  7. If srcLength + targetOffset > targetLength, throw a RangeError exception.
  8. Let k be 0.
  9. Repeat, while k < srcLength,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let value be ? Get(src, Pk).
    3. Let targetIndex be 𝔽(targetOffset + k).
    4. Perform ? TypedArraySetElement(target, targetIndex, value).
    5. Set k to k + 1.
  10. Return unused.

23.2.3.26.2 SetTypedArrayFromTypedArray ( target, targetOffset, source )

The abstract operation SetTypedArrayFromTypedArray takes arguments target (a TypedArray), targetOffset (a non-negative integer or +∞), and source (a TypedArray) and returns either a normal completion containing unused or a throw completion. It sets multiple values in target, starting at index targetOffset, reading the values from source. It performs the following steps when called:

  1. Let targetBuffer be target.[[ViewedArrayBuffer]].
  2. Let targetRecord be MakeTypedArrayWithBufferWitnessRecord(target, seq-cst).
  3. If IsTypedArrayOutOfBounds(targetRecord) is true, throw a TypeError exception.
  4. Let targetLength be TypedArrayLength(targetRecord).
  5. Let srcBuffer be source.[[ViewedArrayBuffer]].
  6. Let srcRecord be MakeTypedArrayWithBufferWitnessRecord(source, seq-cst).
  7. If IsTypedArrayOutOfBounds(srcRecord) is true, throw a TypeError exception.
  8. Let srcLength be TypedArrayLength(srcRecord).
  9. Let targetType be TypedArrayElementType(target).
  10. Let targetElementSize be TypedArrayElementSize(target).
  11. Let targetByteOffset be target.[[ByteOffset]].
  12. Let srcType be TypedArrayElementType(source).
  13. Let srcElementSize be TypedArrayElementSize(source).
  14. Let srcByteOffset be source.[[ByteOffset]].
  15. If targetOffset = +∞, throw a RangeError exception.
  16. If srcLength + targetOffset > targetLength, throw a RangeError exception.
  17. If target.[[ContentType]] is not source.[[ContentType]], throw a TypeError exception.
  18. If IsSharedArrayBuffer(srcBuffer) is true, IsSharedArrayBuffer(targetBuffer) is true, and srcBuffer.[[ArrayBufferData]] is targetBuffer.[[ArrayBufferData]], let sameSharedArrayBuffer be true; otherwise let sameSharedArrayBuffer be false.
  19. If SameValue(srcBuffer, targetBuffer) is true or sameSharedArrayBuffer is true, then
    1. Let srcByteLength be TypedArrayByteLength(srcRecord).
    2. Set srcBuffer to ? CloneArrayBuffer(srcBuffer, srcByteOffset, srcByteLength).
    3. Let srcByteIndex be 0.
  20. Else,
    1. Let srcByteIndex be srcByteOffset.
  21. Let targetByteIndex be (targetOffset × targetElementSize) + targetByteOffset.
  22. Let limit be targetByteIndex + (targetElementSize × srcLength).
  23. If srcType is targetType, then
    1. NOTE: The transfer must be performed in a manner that preserves the bit-level encoding of the source data.
    2. Repeat, while targetByteIndex < limit,
      1. Let value be GetValueFromBuffer(srcBuffer, srcByteIndex, uint8, true, unordered).
      2. Perform SetValueInBuffer(targetBuffer, targetByteIndex, uint8, value, true, unordered).
      3. Set srcByteIndex to srcByteIndex + 1.
      4. Set targetByteIndex to targetByteIndex + 1.
  24. Else,
    1. Repeat, while targetByteIndex < limit,
      1. Let value be GetValueFromBuffer(srcBuffer, srcByteIndex, srcType, true, unordered).
      2. Perform SetValueInBuffer(targetBuffer, targetByteIndex, targetType, value, true, unordered).
      3. Set srcByteIndex to srcByteIndex + srcElementSize.
      4. Set targetByteIndex to targetByteIndex + targetElementSize.
  25. Return unused.

23.2.3.27 %TypedArray%.prototype.slice ( start, end )

The interpretation and use of the arguments of this method are the same as for Array.prototype.slice as defined in 23.1.3.28.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let srcArrayLength be TypedArrayLength(taRecord).
  4. Let relativeStart be ? ToIntegerOrInfinity(start).
  5. If relativeStart = -∞, let startIndex be 0.
  6. Else if relativeStart < 0, let startIndex be max(srcArrayLength + relativeStart, 0).
  7. Else, let startIndex be min(relativeStart, srcArrayLength).
  8. If end is undefined, let relativeEnd be srcArrayLength; else let relativeEnd be ? ToIntegerOrInfinity(end).
  9. If relativeEnd = -∞, let endIndex be 0.
  10. Else if relativeEnd < 0, let endIndex be max(srcArrayLength + relativeEnd, 0).
  11. Else, let endIndex be min(relativeEnd, srcArrayLength).
  12. Let countBytes be max(endIndex - startIndex, 0).
  13. Let A be ? TypedArraySpeciesCreate(O, « 𝔽(countBytes) »).
  14. If countBytes > 0, then
    1. Set taRecord to MakeTypedArrayWithBufferWitnessRecord(O, seq-cst).
    2. If IsTypedArrayOutOfBounds(taRecord) is true, throw a TypeError exception.
    3. Set endIndex to min(endIndex, TypedArrayLength(taRecord)).
    4. Set countBytes to max(endIndex - startIndex, 0).
    5. Let srcType be TypedArrayElementType(O).
    6. Let targetType be TypedArrayElementType(A).
    7. If srcType is targetType, then
      1. NOTE: The transfer must be performed in a manner that preserves the bit-level encoding of the source data.
      2. Let srcBuffer be O.[[ViewedArrayBuffer]].
      3. Let targetBuffer be A.[[ViewedArrayBuffer]].
      4. Let elementSize be TypedArrayElementSize(O).
      5. Let srcByteOffset be O.[[ByteOffset]].
      6. Let srcByteIndex be (startIndex × elementSize) + srcByteOffset.
      7. Let targetByteIndex be A.[[ByteOffset]].
      8. Let endByteIndex be targetByteIndex + (countBytes × elementSize).
      9. Repeat, while targetByteIndex < endByteIndex,
        1. Let value be GetValueFromBuffer(srcBuffer, srcByteIndex, uint8, true, unordered).
        2. Perform SetValueInBuffer(targetBuffer, targetByteIndex, uint8, value, true, unordered).
        3. Set srcByteIndex to srcByteIndex + 1.
        4. Set targetByteIndex to targetByteIndex + 1.
    8. Else,
      1. Let n be 0.
      2. Let k be startIndex.
      3. Repeat, while k < endIndex,
        1. Let Pk be ! ToString(𝔽(k)).
        2. Let kValue be ! Get(O, Pk).
        3. Perform ! Set(A, ! ToString(𝔽(n)), kValue, true).
        4. Set k to k + 1.
        5. Set n to n + 1.
  15. Return A.

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.28 %TypedArray%.prototype.some ( callback [ , thisArg ] )

The interpretation and use of the arguments of this method are the same as for Array.prototype.some as defined in 23.1.3.29.

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. If IsCallable(callback) is false, throw a TypeError exception.
  5. Let k be 0.
  6. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kValue be ! Get(O, Pk).
    3. Let testResult be ToBoolean(? Call(callback, thisArg, « kValue, 𝔽(k), O »)).
    4. If testResult is true, return true.
    5. Set k to k + 1.
  7. Return false.

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.29 %TypedArray%.prototype.sort ( comparator )

This is a distinct method that, except as described below, implements the same requirements as those of Array.prototype.sort as defined in 23.1.3.30. The implementation of this method may be optimized with the knowledge that the this value is an object that has a fixed length and whose integer-indexed properties are not sparse.

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

It performs the following steps when called:

  1. If comparator is not undefined and IsCallable(comparator) is false, throw a TypeError exception.
  2. Let obj be the this value.
  3. Let taRecord be ? ValidateTypedArray(obj, seq-cst).
  4. Let len be TypedArrayLength(taRecord).
  5. NOTE: The following closure performs a numeric comparison rather than the string comparison used in 23.1.3.30.
  6. Let SortCompare be a new Abstract Closure with parameters (x, y) that captures comparator and performs the following steps when called:
    1. Return ? CompareTypedArrayElements(x, y, comparator).
  7. Let sortedList be ? SortIndexedProperties(obj, len, SortCompare, read-through-holes).
  8. Let j be 0.
  9. Repeat, while j < len,
    1. Perform ! Set(obj, ! ToString(𝔽(j)), sortedList[j], true).
    2. Set j to j + 1.
  10. Return obj.
Note

Because NaN always compares greater than any other value (see CompareTypedArrayElements), NaN property values always sort to the end of the result when comparator is not provided.

23.2.3.30 %TypedArray%.prototype.subarray ( start, end )

This method returns a new TypedArray whose element type is the element type of this TypedArray and whose ArrayBuffer is the ArrayBuffer of this TypedArray, referencing the elements in the interval from start (inclusive) to end (exclusive). If either start or end is negative, it refers to an index from the end of the array, as opposed to from the beginning.

It performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[TypedArrayName]]).
  3. Assert: O has a [[ViewedArrayBuffer]] internal slot.
  4. Let buffer be O.[[ViewedArrayBuffer]].
  5. Let srcRecord be MakeTypedArrayWithBufferWitnessRecord(O, seq-cst).
  6. If IsTypedArrayOutOfBounds(srcRecord) is true, then
    1. Let srcLength be 0.
  7. Else,
    1. Let srcLength be TypedArrayLength(srcRecord).
  8. Let relativeStart be ? ToIntegerOrInfinity(start).
  9. If relativeStart = -∞, let startIndex be 0.
  10. Else if relativeStart < 0, let startIndex be max(srcLength + relativeStart, 0).
  11. Else, let startIndex be min(relativeStart, srcLength).
  12. Let elementSize be TypedArrayElementSize(O).
  13. Let srcByteOffset be O.[[ByteOffset]].
  14. Let beginByteOffset be srcByteOffset + (startIndex × elementSize).
  15. If O.[[ArrayLength]] is auto and end is undefined, then
    1. Let argumentsList be « buffer, 𝔽(beginByteOffset) ».
  16. Else,
    1. If end is undefined, let relativeEnd be srcLength; else let relativeEnd be ? ToIntegerOrInfinity(end).
    2. If relativeEnd = -∞, let endIndex be 0.
    3. Else if relativeEnd < 0, let endIndex be max(srcLength + relativeEnd, 0).
    4. Else, let endIndex be min(relativeEnd, srcLength).
    5. Let newLength be max(endIndex - startIndex, 0).
    6. Let argumentsList be « buffer, 𝔽(beginByteOffset), 𝔽(newLength) ».
  17. Return ? TypedArraySpeciesCreate(O, argumentsList).

This method is not generic. The this value must be an object with a [[TypedArrayName]] internal slot.

23.2.3.31 %TypedArray%.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] )

This is a distinct method that implements the same algorithm as Array.prototype.toLocaleString as defined in 23.1.3.32 except that TypedArrayLength is called in place of performing a [[Get]] of "length". The implementation of the algorithm may be optimized with the knowledge that the this value has a fixed length when the underlying buffer is not resizable and whose integer-indexed properties are not sparse. However, such optimization must not introduce any observable changes in the specified behaviour of the algorithm.

This method is not generic. ValidateTypedArray is called with the this value and seq-cst as arguments prior to evaluating the algorithm. If its result is an abrupt completion that exception is thrown instead of evaluating the algorithm.

Note

If the ECMAScript implementation includes the ECMA-402 Internationalization API this method is based upon the algorithm for Array.prototype.toLocaleString that is in the ECMA-402 specification.

23.2.3.32 %TypedArray%.prototype.toReversed ( )

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let length be TypedArrayLength(taRecord).
  4. Let A be ? TypedArrayCreateSameType(O, « 𝔽(length) »).
  5. Let k be 0.
  6. Repeat, while k < length,
    1. Let from be ! ToString(𝔽(length - k - 1)).
    2. Let Pk be ! ToString(𝔽(k)).
    3. Let fromValue be ! Get(O, from).
    4. Perform ! Set(A, Pk, fromValue, true).
    5. Set k to k + 1.
  7. Return A.

23.2.3.33 %TypedArray%.prototype.toSorted ( comparator )

This method performs the following steps when called:

  1. If comparator is not undefined and IsCallable(comparator) is false, throw a TypeError exception.
  2. Let O be the this value.
  3. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  4. Let len be TypedArrayLength(taRecord).
  5. Let A be ? TypedArrayCreateSameType(O, « 𝔽(len) »).
  6. NOTE: The following closure performs a numeric comparison rather than the string comparison used in 23.1.3.34.
  7. Let SortCompare be a new Abstract Closure with parameters (x, y) that captures comparator and performs the following steps when called:
    1. Return ? CompareTypedArrayElements(x, y, comparator).
  8. Let sortedList be ? SortIndexedProperties(O, len, SortCompare, read-through-holes).
  9. Let j be 0.
  10. Repeat, while j < len,
    1. Perform ! Set(A, ! ToString(𝔽(j)), sortedList[j], true).
    2. Set j to j + 1.
  11. Return A.

23.2.3.34 %TypedArray%.prototype.toString ( )

The initial value of the "toString" property is %Array.prototype.toString%, defined in 23.1.3.36.

23.2.3.35 %TypedArray%.prototype.values ( )

This method performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? ValidateTypedArray(O, seq-cst).
  3. Return CreateArrayIterator(O, value).

23.2.3.36 %TypedArray%.prototype.with ( index, value )

This method performs the following steps when called:

  1. Let O be the this value.
  2. Let taRecord be ? ValidateTypedArray(O, seq-cst).
  3. Let len be TypedArrayLength(taRecord).
  4. Let relativeIndex be ? ToIntegerOrInfinity(index).
  5. If relativeIndex ≥ 0, let actualIndex be relativeIndex.
  6. Else, let actualIndex be len + relativeIndex.
  7. If O.[[ContentType]] is bigint, let numericValue be ? ToBigInt(value).
  8. Else, let numericValue be ? ToNumber(value).
  9. If IsValidIntegerIndex(O, 𝔽(actualIndex)) is false, throw a RangeError exception.
  10. Let A be ? TypedArrayCreateSameType(O, « 𝔽(len) »).
  11. Let k be 0.
  12. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. If k = actualIndex, let fromValue be numericValue.
    3. Else, let fromValue be ! Get(O, Pk).
    4. Perform ! Set(A, Pk, fromValue, true).
    5. Set k to k + 1.
  13. Return A.

23.2.3.37 %TypedArray%.prototype [ %Symbol.iterator% ] ( )

The initial value of the %Symbol.iterator% property is %TypedArray.prototype.values%, defined in 23.2.3.35.

23.2.3.38 get %TypedArray%.prototype [ %Symbol.toStringTag% ]

%TypedArray%.prototype[%Symbol.toStringTag%] is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let O be the this value.
  2. If O is not an Object, return undefined.
  3. If O does not have a [[TypedArrayName]] internal slot, return undefined.
  4. Let name be O.[[TypedArrayName]].
  5. Assert: name is a String.
  6. Return name.

This property has the attributes { [[Enumerable]]: false, [[Configurable]]: true }.

The initial value of the "name" property of this function is "get [Symbol.toStringTag]".

23.2.4 Abstract Operations for TypedArray Objects

23.2.4.1 TypedArrayCreateFromConstructor ( constructor, argumentList )

The abstract operation TypedArrayCreateFromConstructor takes arguments constructor (a constructor) and argumentList (a List of ECMAScript language values) and returns either a normal completion containing a TypedArray or a throw completion. It is used to specify the creation of a new TypedArray using a constructor function. It performs the following steps when called:

  1. Let newTypedArray be ? Construct(constructor, argumentList).
  2. Let taRecord be ? ValidateTypedArray(newTypedArray, seq-cst).
  3. Assert: newTypedArray has all the internal slots mentioned in Properties of TypedArray Instances.
  4. If the number of elements in argumentList is 1 and argumentList[0] is a Number, then
    1. If IsTypedArrayOutOfBounds(taRecord) is true, throw a TypeError exception.
    2. Let length be TypedArrayLength(taRecord).
    3. If length < (argumentList[0]), throw a TypeError exception.
  5. Return newTypedArray.

23.2.4.2 TypedArrayCreateSameType ( exemplar, argumentList )

The abstract operation TypedArrayCreateSameType takes arguments exemplar (a TypedArray) and argumentList (a List of ECMAScript language values) and returns either a normal completion containing a TypedArray or a throw completion. It is used to specify the creation of a new TypedArray using a constructor function that is derived from exemplar. Unlike TypedArraySpeciesCreate, which can construct custom TypedArray subclasses through the use of %Symbol.species%, this operation always uses one of the built-in TypedArray constructors. It performs the following steps when called:

  1. Let constructor be the intrinsic object associated with the constructor name exemplar.[[TypedArrayName]] in Table 75.
  2. Let result be ? TypedArrayCreateFromConstructor(constructor, argumentList).
  3. Assert: result.[[ContentType]] is exemplar.[[ContentType]].
  4. Return result.

23.2.4.3 TypedArraySpeciesCreate ( exemplar, argumentList )

The abstract operation TypedArraySpeciesCreate takes arguments exemplar (a TypedArray) and argumentList (a List of ECMAScript language values) and returns either a normal completion containing a TypedArray or a throw completion. It is used to specify the creation of a new TypedArray using a constructor function that is derived from exemplar. Unlike ArraySpeciesCreate, which can create non-Array objects through the use of %Symbol.species%, this operation enforces that the constructor function creates an actual TypedArray. It performs the following steps when called:

  1. Let defaultConstructor be the intrinsic object associated with the constructor name exemplar.[[TypedArrayName]] in Table 75.
  2. Let constructor be ? SpeciesConstructor(exemplar, defaultConstructor).
  3. Let result be ? TypedArrayCreateFromConstructor(constructor, argumentList).
  4. If result.[[ContentType]] is not exemplar.[[ContentType]], throw a TypeError exception.
  5. Return result.

23.2.4.4 ValidateTypedArray ( O, order )

The abstract operation ValidateTypedArray takes arguments O (an ECMAScript language value) and order (seq-cst or unordered) and returns either a normal completion containing a TypedArray With Buffer Witness Record or a throw completion. It performs the following steps when called:

  1. Perform ? RequireInternalSlot(O, [[TypedArrayName]]).
  2. Assert: O has a [[ViewedArrayBuffer]] internal slot.
  3. Let taRecord be MakeTypedArrayWithBufferWitnessRecord(O, order).
  4. If IsTypedArrayOutOfBounds(taRecord) is true, throw a TypeError exception.
  5. Return taRecord.

23.2.4.5 TypedArrayElementSize ( O )

The abstract operation TypedArrayElementSize takes argument O (a TypedArray) and returns a non-negative integer. It performs the following steps when called:

  1. Return the Element Size value specified in Table 75 for O.[[TypedArrayName]].

23.2.4.6 TypedArrayElementType ( O )

The abstract operation TypedArrayElementType takes argument O (a TypedArray) and returns a TypedArray element type. It performs the following steps when called:

  1. Return the Element Type value specified in Table 75 for O.[[TypedArrayName]].

23.2.4.7 CompareTypedArrayElements ( x, y, comparator )

The abstract operation CompareTypedArrayElements takes arguments x (a Number or a BigInt), y (a Number or a BigInt), and comparator (a function object or undefined) and returns either a normal completion containing a Number or an abrupt completion. It performs the following steps when called:

  1. Assert: x is a Number and y is a Number, or x is a BigInt and y is a BigInt.
  2. If comparator is not undefined, then
    1. Let v be ? ToNumber(? Call(comparator, undefined, « x, y »)).
    2. If v is NaN, return +0𝔽.
    3. Return v.
  3. If x and y are both NaN, return +0𝔽.
  4. If x is NaN, return 1𝔽.
  5. If y is NaN, return -1𝔽.
  6. If x < y, return -1𝔽.
  7. If x > y, return 1𝔽.
  8. If x is -0𝔽 and y is +0𝔽, return -1𝔽.
  9. If x is +0𝔽 and y is -0𝔽, return 1𝔽.
  10. Return +0𝔽.
Note
This performs a numeric comparison rather than the string comparison used in 23.1.3.30.2.

23.2.5 The TypedArray Constructors

Each TypedArray constructor:

  • is an intrinsic object that has the structure described below, differing only in the name used as the constructor name instead of TypedArray, in Table 75.
  • is a function whose behaviour differs based upon the number and types of its arguments. The actual behaviour of a call of TypedArray depends upon the number and kind of arguments that are passed to it.
  • is not intended to be called as a function and will throw an exception when called in that manner.
  • may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified TypedArray behaviour must include a super call to the TypedArray constructor to create and initialize the subclass instance with the internal state necessary to support the %TypedArray%.prototype built-in methods.

23.2.5.1 TypedArray ( ...args )

Each TypedArray constructor performs the following steps when called:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. Let constructorName be the String value of the Constructor Name value specified in Table 75 for this TypedArray constructor.
  3. Let proto be "%TypedArray.prototype%".
  4. Let numberOfArgs be the number of elements in args.
  5. If numberOfArgs = 0, then
    1. Return ? AllocateTypedArray(constructorName, NewTarget, proto, 0).
  6. Else,
    1. Let firstArgument be args[0].
    2. If firstArgument is an Object, then
      1. Let O be ? AllocateTypedArray(constructorName, NewTarget, proto).
      2. If firstArgument has a [[TypedArrayName]] internal slot, then
        1. Perform ? InitializeTypedArrayFromTypedArray(O, firstArgument).
      3. Else if firstArgument has an [[ArrayBufferData]] internal slot, then
        1. If numberOfArgs > 1, let byteOffset be args[1]; else let byteOffset be undefined.
        2. If numberOfArgs > 2, let length be args[2]; else let length be undefined.
        3. Perform ? InitializeTypedArrayFromArrayBuffer(O, firstArgument, byteOffset, length).
      4. Else,
        1. Assert: firstArgument is an Object and firstArgument does not have either a [[TypedArrayName]] or an [[ArrayBufferData]] internal slot.
        2. Let usingIterator be ? GetMethod(firstArgument, %Symbol.iterator%).
        3. If usingIterator is not undefined, then
          1. Let values be ? IteratorToList(? GetIteratorFromMethod(firstArgument, usingIterator)).
          2. Perform ? InitializeTypedArrayFromList(O, values).
        4. Else,
          1. NOTE: firstArgument is not an iterable object, so assume it is already an array-like object.
          2. Perform ? InitializeTypedArrayFromArrayLike(O, firstArgument).
      5. Return O.
    3. Else,
      1. Assert: firstArgument is not an Object.
      2. Let elementLength be ? ToIndex(firstArgument).
      3. Return ? AllocateTypedArray(constructorName, NewTarget, proto, elementLength).

23.2.5.1.1 AllocateTypedArray ( constructorName, newTarget, defaultProto [ , length ] )

The abstract operation AllocateTypedArray takes arguments constructorName (a String which is the name of a TypedArray constructor in Table 75), newTarget (a constructor), and defaultProto (a String) and optional argument length (a non-negative integer) and returns either a normal completion containing a TypedArray or a throw completion. It is used to validate and create an instance of a TypedArray constructor. If the length argument is passed, an ArrayBuffer of that length is also allocated and associated with the new TypedArray instance. AllocateTypedArray provides common semantics that is used by TypedArray. It performs the following steps when called:

  1. Let proto be ? GetPrototypeFromConstructor(newTarget, defaultProto).
  2. Let obj be TypedArrayCreate(proto).
  3. Assert: obj.[[ViewedArrayBuffer]] is undefined.
  4. Set obj.[[TypedArrayName]] to constructorName.
  5. If constructorName is either "BigInt64Array" or "BigUint64Array", set obj.[[ContentType]] to bigint.
  6. Otherwise, set obj.[[ContentType]] to number.
  7. If length is not present, then
    1. Set obj.[[ByteLength]] to 0.
    2. Set obj.[[ByteOffset]] to 0.
    3. Set obj.[[ArrayLength]] to 0.
  8. Else,
    1. Perform ? AllocateTypedArrayBuffer(obj, length).
  9. Return obj.

23.2.5.1.2 InitializeTypedArrayFromTypedArray ( O, srcArray )

The abstract operation InitializeTypedArrayFromTypedArray takes arguments O (a TypedArray) and srcArray (a TypedArray) and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:

  1. Let srcData be srcArray.[[ViewedArrayBuffer]].
  2. Let elementType be TypedArrayElementType(O).
  3. Let elementSize be TypedArrayElementSize(O).
  4. Let srcType be TypedArrayElementType(srcArray).
  5. Let srcElementSize be TypedArrayElementSize(srcArray).
  6. Let srcByteOffset be srcArray.[[ByteOffset]].
  7. Let srcRecord be MakeTypedArrayWithBufferWitnessRecord(srcArray, seq-cst).
  8. If IsTypedArrayOutOfBounds(srcRecord) is true, throw a TypeError exception.
  9. Let elementLength be TypedArrayLength(srcRecord).
  10. Let byteLength be elementSize × elementLength.
  11. If elementType is srcType, then
    1. Let data be ? CloneArrayBuffer(srcData, srcByteOffset, byteLength).
  12. Else,
    1. Let data be ? AllocateArrayBuffer(%ArrayBuffer%, byteLength).
    2. If srcArray.[[ContentType]] is not O.[[ContentType]], throw a TypeError exception.
    3. Let srcByteIndex be srcByteOffset.
    4. Let targetByteIndex be 0.
    5. Let count be elementLength.
    6. Repeat, while count > 0,
      1. Let value be GetValueFromBuffer(srcData, srcByteIndex, srcType, true, unordered).
      2. Perform SetValueInBuffer(data, targetByteIndex, elementType, value, true, unordered).
      3. Set srcByteIndex to srcByteIndex + srcElementSize.
      4. Set targetByteIndex to targetByteIndex + elementSize.
      5. Set count to count - 1.
  13. Set O.[[ViewedArrayBuffer]] to data.
  14. Set O.[[ByteLength]] to byteLength.
  15. Set O.[[ByteOffset]] to 0.
  16. Set O.[[ArrayLength]] to elementLength.
  17. Return unused.

23.2.5.1.3 InitializeTypedArrayFromArrayBuffer ( O, buffer, byteOffset, length )

The abstract operation InitializeTypedArrayFromArrayBuffer takes arguments O (a TypedArray), buffer (an ArrayBuffer or a SharedArrayBuffer), byteOffset (an ECMAScript language value), and length (an ECMAScript language value) and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:

  1. Let elementSize be TypedArrayElementSize(O).
  2. Let offset be ? ToIndex(byteOffset).
  3. If offset modulo elementSize ≠ 0, throw a RangeError exception.
  4. Let bufferIsFixedLength be IsFixedLengthArrayBuffer(buffer).
  5. If length is not undefined, then
    1. Let newLength be ? ToIndex(length).
  6. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
  7. Let bufferByteLength be ArrayBufferByteLength(buffer, seq-cst).
  8. If length is undefined and bufferIsFixedLength is false, then
    1. If offset > bufferByteLength, throw a RangeError exception.
    2. Set O.[[ByteLength]] to auto.
    3. Set O.[[ArrayLength]] to auto.
  9. Else,
    1. If length is undefined, then
      1. If bufferByteLength modulo elementSize ≠ 0, throw a RangeError exception.
      2. Let newByteLength be bufferByteLength - offset.
      3. If newByteLength < 0, throw a RangeError exception.
    2. Else,
      1. Let newByteLength be newLength × elementSize.
      2. If offset + newByteLength > bufferByteLength, throw a RangeError exception.
    3. Set O.[[ByteLength]] to newByteLength.
    4. Set O.[[ArrayLength]] to newByteLength / elementSize.
  10. Set O.[[ViewedArrayBuffer]] to buffer.
  11. Set O.[[ByteOffset]] to offset.
  12. Return unused.

23.2.5.1.4 InitializeTypedArrayFromList ( O, values )

The abstract operation InitializeTypedArrayFromList takes arguments O (a TypedArray) and values (a List of ECMAScript language values) and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:

  1. Let len be the number of elements in values.
  2. Perform ? AllocateTypedArrayBuffer(O, len).
  3. Let k be 0.
  4. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kValue be the first element of values.
    3. Remove the first element from values.
    4. Perform ? Set(O, Pk, kValue, true).
    5. Set k to k + 1.
  5. Assert: values is now an empty List.
  6. Return unused.

23.2.5.1.5 InitializeTypedArrayFromArrayLike ( O, arrayLike )

The abstract operation InitializeTypedArrayFromArrayLike takes arguments O (a TypedArray) and arrayLike (an Object, but not a TypedArray or an ArrayBuffer) and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:

  1. Let len be ? LengthOfArrayLike(arrayLike).
  2. Perform ? AllocateTypedArrayBuffer(O, len).
  3. Let k be 0.
  4. Repeat, while k < len,
    1. Let Pk be ! ToString(𝔽(k)).
    2. Let kValue be ? Get(arrayLike, Pk).
    3. Perform ? Set(O, Pk, kValue, true).
    4. Set k to k + 1.
  5. Return unused.

23.2.5.1.6 AllocateTypedArrayBuffer ( O, length )

The abstract operation AllocateTypedArrayBuffer takes arguments O (a TypedArray) and length (a non-negative integer) and returns either a normal completion containing unused or a throw completion. It allocates and associates an ArrayBuffer with O. It performs the following steps when called:

  1. Assert: O.[[ViewedArrayBuffer]] is undefined.
  2. Let elementSize be TypedArrayElementSize(O).
  3. Let byteLength be elementSize × length.
  4. Let data be ? AllocateArrayBuffer(%ArrayBuffer%, byteLength).
  5. Set O.[[ViewedArrayBuffer]] to data.
  6. Set O.[[ByteLength]] to byteLength.
  7. Set O.[[ByteOffset]] to 0.
  8. Set O.[[ArrayLength]] to length.
  9. Return unused.

23.2.6 Properties of the TypedArray Constructors

Each TypedArray constructor:

  • has a [[Prototype]] internal slot whose value is %TypedArray%.
  • has a "length" property whose value is 3𝔽.
  • has a "name" property whose value is the String value of the constructor name specified for it in Table 75.
  • has the following properties:

23.2.6.1 TypedArray.BYTES_PER_ELEMENT

The value of TypedArray.BYTES_PER_ELEMENT is the Element Size value specified in Table 75 for TypedArray.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

23.2.6.2 TypedArray.prototype

The initial value of TypedArray.prototype is the corresponding TypedArray prototype intrinsic object (23.2.7).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

23.2.7 Properties of the TypedArray Prototype Objects

Each TypedArray prototype object:

  • has a [[Prototype]] internal slot whose value is %TypedArray.prototype%.
  • is an ordinary object.
  • does not have a [[ViewedArrayBuffer]] or any other of the internal slots that are specific to TypedArray instance objects.

23.2.7.1 TypedArray.prototype.BYTES_PER_ELEMENT

The value of TypedArray.prototype.BYTES_PER_ELEMENT is the Element Size value specified in Table 75 for TypedArray.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

23.2.7.2 TypedArray.prototype.constructor

The initial value of the "constructor" property of the prototype for a given TypedArray constructor is the constructor itself.

23.2.8 Properties of TypedArray Instances

TypedArray instances are TypedArrays. Each TypedArray instance inherits properties from the corresponding TypedArray prototype object. Each TypedArray instance has the following internal slots: [[ViewedArrayBuffer]], [[TypedArrayName]], [[ContentType]], [[ByteLength]], [[ByteOffset]], and [[ArrayLength]].

24 Keyed Collections

24.1 Map Objects

Maps are collections of key/value pairs where both the keys and values may be arbitrary ECMAScript language values. A distinct key value may only occur in one key/value pair within the Map's collection. Distinct key values are discriminated using the semantics of the SameValueZero comparison algorithm.

Maps must be implemented using either hash tables or other mechanisms that, on average, provide access times that are sublinear on the number of elements in the collection. The data structure used in this specification is only intended to describe the required observable semantics of Maps. It is not intended to be a viable implementation model.

24.1.1 The Map Constructor

The Map constructor:

  • is %Map%.
  • is the initial value of the "Map" property of the global object.
  • creates and initializes a new Map when called as a constructor.
  • is not intended to be called as a function and will throw an exception when called in that manner.
  • may be used as the value in an extends clause of a class definition. Subclass constructors that intend to inherit the specified Map behaviour must include a super call to the Map constructor to create and initialize the subclass instance with the internal state necessary to support the Map.prototype built-in methods.

24.1.1.1 Map ( [ iterable ] )

This function performs the following steps when called:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. Let map be ? OrdinaryCreateFromConstructor(NewTarget, "%Map.prototype%", « [[MapData]] »).
  3. Set map.[[MapData]] to a new empty List.
  4. If iterable is either undefined or null, return map.
  5. Let adder be ? Get(map, "set").
  6. If IsCallable(adder) is false, throw a TypeError exception.
  7. Return ? AddEntriesFromIterable(map, iterable, adder).
Note

If the parameter iterable is present, it is expected to be an object that implements a %Symbol.iterator% method that returns an iterator object that produces a two element array-like object whose first element is a value that will be used as a Map key and whose second element is the value to associate with that key.

24.1.1.2 AddEntriesFromIterable ( target, iterable, adder )

The abstract operation AddEntriesFromIterable takes arguments target (an Object), iterable (an ECMAScript language value, but not undefined or null), and adder (a function object) and returns either a normal completion containing an ECMAScript language value or a throw completion. adder will be invoked, with target as the receiver. It performs the following steps when called:

  1. Let iteratorRecord be ? GetIterator(iterable, sync).
  2. Repeat,
    1. Let next be ? IteratorStepValue(iteratorRecord).
    2. If next is done, return target.
    3. If next is not an Object, then
      1. Let error be ThrowCompletion(a newly created TypeError object).
      2. Return ? IteratorClose(iteratorRecord, error).
    4. Let k be Completion(Get(next, "0")).
    5. IfAbruptCloseIterator(k, iteratorRecord).
    6. Let v be Completion(Get(next, "1")).
    7. IfAbruptCloseIterator(v, iteratorRecord).
    8. Let status be Completion(Call(adder, target, « k, v »)).
    9. IfAbruptCloseIterator(status, iteratorRecord).
Note

The parameter iterable is expected to be an object that implements a %Symbol.iterator% method that returns an iterator object that produces a two element array-like object whose first element is a value that will be used as a Map key and whose second element is the value to associate with that key.

24.1.2 Properties of the Map Constructor

The Map constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

24.1.2.1 Map.groupBy ( items, callback )

Note

callback should be a function that accepts two arguments. groupBy calls callback once for each element in items, in ascending order, and constructs a new Map. Each value returned by callback is used as a key in the Map. For each such key, the result Map has an entry whose key is that key and whose value is an array containing all the elements for which callback returned that key.

callback is called with two arguments: the value of the element and the index of the element.

The return value of groupBy is a Map.

This function performs the following steps when called:

  1. Let groups be ? GroupBy(items, callback, collection).
  2. Let map be ! Construct(%Map%).
  3. For each Record { [[Key]], [[Elements]] } g of groups, do
    1. Let elements be CreateArrayFromList(g.[[Elements]]).
    2. Let entry be the Record { [[Key]]: g.[[Key]], [[Value]]: elements }.
    3. Append entry to map.[[MapData]].
  4. Return map.

24.1.2.2 Map.prototype

The initial value of Map.prototype is the Map prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

24.1.2.3 get Map [ %Symbol.species% ]

Map[%Symbol.species%] is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Return the this value.

The value of the "name" property of this function is "get [Symbol.species]".

Note

Methods that create derived collection objects should call %Symbol.species% to determine the constructor to use to create the derived objects. Subclass constructor may over-ride %Symbol.species% to change the default constructor assignment.

24.1.3 Properties of the Map Prototype Object

The Map prototype object:

24.1.3.1 Map.prototype.clear ( )

This method performs the following steps when called:

  1. Let M be the this value.
  2. Perform ? RequireInternalSlot(M, [[MapData]]).
  3. For each Record { [[Key]], [[Value]] } p of M.[[MapData]], do
    1. Set p.[[Key]] to empty.
    2. Set p.[[Value]] to empty.
  4. Return undefined.
Note

The existing [[MapData]] List is preserved because there may be existing Map Iterator objects that are suspended midway through iterating over that List.

24.1.3.2 Map.prototype.constructor

The initial value of Map.prototype.constructor is %Map%.

24.1.3.3 Map.prototype.delete ( key )

This method performs the following steps when called:

  1. Let M be the this value.
  2. Perform ? RequireInternalSlot(M, [[MapData]]).
  3. Set key to CanonicalizeKeyedCollectionKey(key).
  4. For each Record { [[Key]], [[Value]] } p of M.[[MapData]], do
    1. If p.[[Key]] is not empty and SameValue(p.[[Key]], key) is true, then
      1. Set p.[[Key]] to empty.
      2. Set p.[[Value]] to empty.
      3. Return true.
  5. Return false.
Note

The value empty is used as a specification device to indicate that an entry has been deleted. Actual implementations may take other actions such as physically removing the entry from internal data structures.

24.1.3.4 Map.prototype.entries ( )

This method performs the following steps when called:

  1. Let M be the this value.
  2. Return ? CreateMapIterator(M, key+value).

24.1.3.5 Map.prototype.forEach ( callback [ , thisArg ] )

This method performs the following steps when called:

  1. Let M be the this value.
  2. Perform ? RequireInternalSlot(M, [[MapData]]).
  3. If IsCallable(callback) is false, throw a TypeError exception.
  4. Let entries be M.[[MapData]].
  5. Let numEntries be the number of elements in entries.
  6. Let index be 0.
  7. Repeat, while index < numEntries,
    1. Let e be entries[index].
    2. Set index to index + 1.
    3. If e.[[Key]] is not empty, then
      1. Perform ? Call(callback, thisArg, « e.[[Value]], e.[[Key]], M »).
      2. NOTE: The number of elements in entries may have increased during execution of callback.
      3. Set numEntries to the number of elements in entries.
  8. Return undefined.
Note

callback should be a function that accepts three arguments. forEach calls callback once for each key/value pair present in the Map, in key insertion order. callback is called only for keys of the Map which actually exist; it is not called for keys that have been deleted from the Map.

If a thisArg parameter is provided, it will be used as the this value for each invocation of callback. If it is not provided, undefined is used instead.

callback is called with three arguments: the value of the item, the key of the item, and the Map being traversed.

forEach does not directly mutate the object on which it is called but the object may be mutated by the calls to callback. Each entry of a map's [[MapData]] is only visited once. New keys added after the call to forEach begins are visited. A key will be revisited if it is deleted after it has been visited and then re-added before the forEach call completes. Keys that are deleted after the call to forEach begins and before being visited are not visited unless the key is added again before the forEach call completes.

24.1.3.6 Map.prototype.get ( key )

This method performs the following steps when called:

  1. Let M be the this value.
  2. Perform ? RequireInternalSlot(M, [[MapData]]).
  3. Set key to CanonicalizeKeyedCollectionKey(key).
  4. For each Record { [[Key]], [[Value]] } p of M.[[MapData]], do
    1. If p.[[Key]] is not empty and SameValue(p.[[Key]], key) is true, return p.[[Value]].
  5. Return undefined.

24.1.3.7 Map.prototype.has ( key )

This method performs the following steps when called:

  1. Let M be the this value.
  2. Perform ? RequireInternalSlot(M, [[MapData]]).
  3. Set key to CanonicalizeKeyedCollectionKey(key).
  4. For each Record { [[Key]], [[Value]] } p of M.[[MapData]], do
    1. If p.[[Key]] is not empty and SameValue(p.[[Key]], key) is true, return true.
  5. Return false.

24.1.3.8 Map.prototype.keys ( )

This method performs the following steps when called:

  1. Let M be the this value.
  2. Return ? CreateMapIterator(M, key).

24.1.3.9 Map.prototype.set ( key, value )

This method performs the following steps when called:

  1. Let M be the this value.
  2. Perform ? RequireInternalSlot(M, [[MapData]]).
  3. Set key to CanonicalizeKeyedCollectionKey(key).
  4. For each Record { [[Key]], [[Value]] } p of M.[[MapData]], do
    1. If p.[[Key]] is not empty and SameValue(p.[[Key]], key) is true, then
      1. Set p.[[Value]] to value.
      2. Return M.
  5. Let p be the Record { [[Key]]: key, [[Value]]: value }.
  6. Append p to M.[[MapData]].
  7. Return M.

24.1.3.10 get Map.prototype.size

Map.prototype.size is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let M be the this value.
  2. Perform ? RequireInternalSlot(M, [[MapData]]).
  3. Let count be 0.
  4. For each Record { [[Key]], [[Value]] } p of M.[[MapData]], do
    1. If p.[[Key]] is not empty, set count to count + 1.
  5. Return 𝔽(count).

24.1.3.11 Map.prototype.values ( )

This method performs the following steps when called:

  1. Let M be the this value.
  2. Return ? CreateMapIterator(M, value).

24.1.3.12 Map.prototype [ %Symbol.iterator% ] ( )

The initial value of the %Symbol.iterator% property is %Map.prototype.entries%, defined in 24.1.3.4.

24.1.3.13 Map.prototype [ %Symbol.toStringTag% ]

The initial value of the %Symbol.toStringTag% property is the String value "Map".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

24.1.4 Properties of Map Instances

Map instances are ordinary objects that inherit properties from the Map prototype object. Map instances also have a [[MapData]] internal slot.

24.1.5 Map Iterator Objects

A Map Iterator is an object that represents a specific iteration over some specific Map instance object. There is not a named constructor for Map Iterator objects. Instead, Map Iterator objects are created by calling certain methods of Map instance objects.

24.1.5.1 CreateMapIterator ( map, kind )

The abstract operation CreateMapIterator takes arguments map (an ECMAScript language value) and kind (key+value, key, or value) and returns either a normal completion containing a Generator or a throw completion. It is used to create iterator objects for Map methods that return such iterators. It performs the following steps when called:

  1. Perform ? RequireInternalSlot(map, [[MapData]]).
  2. Let closure be a new Abstract Closure with no parameters that captures map and kind and performs the following steps when called:
    1. Let entries be map.[[MapData]].
    2. Let index be 0.
    3. Let numEntries be the number of elements in entries.
    4. Repeat, while index < numEntries,
      1. Let e be entries[index].
      2. Set index to index + 1.
      3. If e.[[Key]] is not empty, then
        1. If kind is key, then
          1. Let result be e.[[Key]].
        2. Else if kind is value, then
          1. Let result be e.[[Value]].
        3. Else,
          1. Assert: kind is key+value.
          2. Let result be CreateArrayFromListe.[[Key]], e.[[Value]] »).
        4. Perform ? GeneratorYield(CreateIteratorResultObject(result, false)).
        5. NOTE: The number of elements in entries may have increased while execution of this abstract operation was paused by GeneratorYield.
        6. Set numEntries to the number of elements in entries.
    5. Return NormalCompletion(unused).
  3. Return CreateIteratorFromClosure(closure, "%MapIteratorPrototype%", %MapIteratorPrototype%).

24.1.5.2 The %MapIteratorPrototype% Object

The %MapIteratorPrototype% object:

24.1.5.2.1 %MapIteratorPrototype%.next ( )

  1. Return ? GeneratorResume(this value, empty, "%MapIteratorPrototype%").

24.1.5.2.2 %MapIteratorPrototype% [ %Symbol.toStringTag% ]

The initial value of the %Symbol.toStringTag% property is the String value "Map Iterator".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

24.2 Set Objects

Set objects are collections of ECMAScript language values. A distinct value may only occur once as an element of a Set's collection. Distinct values are discriminated using the semantics of the SameValueZero comparison algorithm.

Set objects must be implemented using either hash tables or other mechanisms that, on average, provide access times that are sublinear on the number of elements in the collection. The data structure used in this specification is only intended to describe the required observable semantics of Set objects. It is not intended to be a viable implementation model.

24.2.1 Abstract Operations For Set Objects

24.2.1.1 Set Records

A Set Record is a Record value used to encapsulate the interface of a Set or similar object.

Set Records have the fields listed in Table 76.

Table 76: Set Record Fields
Field Name Value Meaning
[[SetObject]] an Object the Set or similar object.
[[Size]] a non-negative integer or +∞ The reported size of the object.
[[Has]] a function object The has method of the object.
[[Keys]] a function object The keys method of the object.

24.2.1.2 GetSetRecord ( obj )

The abstract operation GetSetRecord takes argument obj (an ECMAScript language value) and returns either a normal completion containing a Set Record or a throw completion. It performs the following steps when called:

  1. If obj is not an Object, throw a TypeError exception.
  2. Let rawSize be ? Get(obj, "size").
  3. Let numSize be ? ToNumber(rawSize).
  4. NOTE: If rawSize is undefined, then numSize will be NaN.
  5. If numSize is NaN, throw a TypeError exception.
  6. Let intSize be ! ToIntegerOrInfinity(numSize).
  7. If intSize < 0, throw a RangeError exception.
  8. Let has be ? Get(obj, "has").
  9. If IsCallable(has) is false, throw a TypeError exception.
  10. Let keys be ? Get(obj, "keys").
  11. If IsCallable(keys) is false, throw a TypeError exception.
  12. Return a new Set Record { [[SetObject]]: obj, [[Size]]: intSize, [[Has]]: has, [[Keys]]: keys }.

24.2.1.3 SetDataHas ( setData, value )

The abstract operation SetDataHas takes arguments setData (a List of either ECMAScript language values or empty) and value (an ECMAScript language value) and returns a Boolean. It performs the following steps when called:

  1. If SetDataIndex(setData, value) is not-found, return false.
  2. Return true.

24.2.1.4 SetDataIndex ( setData, value )

The abstract operation SetDataIndex takes arguments setData (a List of either ECMAScript language values or empty) and value (an ECMAScript language value) and returns a non-negative integer or not-found. It performs the following steps when called:

  1. Set value to CanonicalizeKeyedCollectionKey(value).
  2. Let size be the number of elements in setData.
  3. Let index be 0.
  4. Repeat, while index < size,
    1. Let e be setData[index].
    2. If e is not empty and e is value, then
      1. Return index.
    3. Set index to index + 1.
  5. Return not-found.

24.2.1.5 SetDataSize ( setData )

The abstract operation SetDataSize takes argument setData (a List of either ECMAScript language values or empty) and returns a non-negative integer. It performs the following steps when called:

  1. Let count be 0.
  2. For each element e of setData, do
    1. If e is not empty, set count to count + 1.
  3. Return count.

24.2.2 The Set Constructor

The Set constructor:

  • is %Set%.
  • is the initial value of the "Set" property of the global object.
  • creates and initializes a new Set object when called as a constructor.
  • is not intended to be called as a function and will throw an exception when called in that manner.
  • may be used as the value in an extends clause of a class definition. Subclass constructors that intend to inherit the specified Set behaviour must include a super call to the Set constructor to create and initialize the subclass instance with the internal state necessary to support the Set.prototype built-in methods.

24.2.2.1 Set ( [ iterable ] )

This function performs the following steps when called:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. Let set be ? OrdinaryCreateFromConstructor(NewTarget, "%Set.prototype%", « [[SetData]] »).
  3. Set set.[[SetData]] to a new empty List.
  4. If iterable is either undefined or null, return set.
  5. Let adder be ? Get(set, "add").
  6. If IsCallable(adder) is false, throw a TypeError exception.
  7. Let iteratorRecord be ? GetIterator(iterable, sync).
  8. Repeat,
    1. Let next be ? IteratorStepValue(iteratorRecord).
    2. If next is done, return set.
    3. Let status be Completion(Call(adder, set, « next »)).
    4. IfAbruptCloseIterator(status, iteratorRecord).

24.2.3 Properties of the Set Constructor

The Set constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

24.2.3.1 Set.prototype

The initial value of Set.prototype is the Set prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

24.2.3.2 get Set [ %Symbol.species% ]

Set[%Symbol.species%] is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Return the this value.

The value of the "name" property of this function is "get [Symbol.species]".

Note

Methods that create derived collection objects should call %Symbol.species% to determine the constructor to use to create the derived objects. Subclass constructor may over-ride %Symbol.species% to change the default constructor assignment.

24.2.4 Properties of the Set Prototype Object

The Set prototype object:

24.2.4.1 Set.prototype.add ( value )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Perform ? RequireInternalSlot(S, [[SetData]]).
  3. Set value to CanonicalizeKeyedCollectionKey(value).
  4. For each element e of S.[[SetData]], do
    1. If e is not empty and SameValue(e, value) is true, then
      1. Return S.
  5. Append value to S.[[SetData]].
  6. Return S.

24.2.4.2 Set.prototype.clear ( )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Perform ? RequireInternalSlot(S, [[SetData]]).
  3. For each element e of S.[[SetData]], do
    1. Replace the element of S.[[SetData]] whose value is e with an element whose value is empty.
  4. Return undefined.
Note

The existing [[SetData]] List is preserved because there may be existing Set Iterator objects that are suspended midway through iterating over that List.

24.2.4.3 Set.prototype.constructor

The initial value of Set.prototype.constructor is %Set%.

24.2.4.4 Set.prototype.delete ( value )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Perform ? RequireInternalSlot(S, [[SetData]]).
  3. Set value to CanonicalizeKeyedCollectionKey(value).
  4. For each element e of S.[[SetData]], do
    1. If e is not empty and SameValue(e, value) is true, then
      1. Replace the element of S.[[SetData]] whose value is e with an element whose value is empty.
      2. Return true.
  5. Return false.
Note

The value empty is used as a specification device to indicate that an entry has been deleted. Actual implementations may take other actions such as physically removing the entry from internal data structures.

24.2.4.5 Set.prototype.difference ( other )

This method performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[SetData]]).
  3. Let otherRec be ? GetSetRecord(other).
  4. Let resultSetData be a copy of O.[[SetData]].
  5. If SetDataSize(O.[[SetData]]) ≤ otherRec.[[Size]], then
    1. Let thisSize be the number of elements in O.[[SetData]].
    2. Let index be 0.
    3. Repeat, while index < thisSize,
      1. Let e be resultSetData[index].
      2. If e is not empty, then
        1. Let inOther be ToBoolean(? Call(otherRec.[[Has]], otherRec.[[SetObject]], « e »)).
        2. If inOther is true, then
          1. Set resultSetData[index] to empty.
      3. Set index to index + 1.
  6. Else,
    1. Let keysIter be ? GetIteratorFromMethod(otherRec.[[SetObject]], otherRec.[[Keys]]).
    2. Let next be not-started.
    3. Repeat, while next is not done,
      1. Set next to ? IteratorStepValue(keysIter).
      2. If next is not done, then
        1. Set next to CanonicalizeKeyedCollectionKey(next).
        2. Let valueIndex be SetDataIndex(resultSetData, next).
        3. If valueIndex is not not-found, then
          1. Set resultSetData[valueIndex] to empty.
  7. Let result be OrdinaryObjectCreate(%Set.prototype%, « [[SetData]] »).
  8. Set result.[[SetData]] to resultSetData.
  9. Return result.

24.2.4.6 Set.prototype.entries ( )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Return ? CreateSetIterator(S, key+value).
Note

For iteration purposes, a Set appears similar to a Map where each entry has the same value for its key and value.

24.2.4.7 Set.prototype.forEach ( callback [ , thisArg ] )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Perform ? RequireInternalSlot(S, [[SetData]]).
  3. If IsCallable(callback) is false, throw a TypeError exception.
  4. Let entries be S.[[SetData]].
  5. Let numEntries be the number of elements in entries.
  6. Let index be 0.
  7. Repeat, while index < numEntries,
    1. Let e be entries[index].
    2. Set index to index + 1.
    3. If e is not empty, then
      1. Perform ? Call(callback, thisArg, « e, e, S »).
      2. NOTE: The number of elements in entries may have increased during execution of callback.
      3. Set numEntries to the number of elements in entries.
  8. Return undefined.
Note

callback should be a function that accepts three arguments. forEach calls callback once for each value present in the Set object, in value insertion order. callback is called only for values of the Set which actually exist; it is not called for keys that have been deleted from the set.

If a thisArg parameter is provided, it will be used as the this value for each invocation of callback. If it is not provided, undefined is used instead.

callback is called with three arguments: the first two arguments are a value contained in the Set. The same value is passed for both arguments. The Set object being traversed is passed as the third argument.

The callback is called with three arguments to be consistent with the call back functions used by forEach methods for Map and Array. For Sets, each item value is considered to be both the key and the value.

forEach does not directly mutate the object on which it is called but the object may be mutated by the calls to callback.

Each value is normally visited only once. However, a value will be revisited if it is deleted after it has been visited and then re-added before the forEach call completes. Values that are deleted after the call to forEach begins and before being visited are not visited unless the value is added again before the forEach call completes. New values added after the call to forEach begins are visited.

24.2.4.8 Set.prototype.has ( value )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Perform ? RequireInternalSlot(S, [[SetData]]).
  3. Set value to CanonicalizeKeyedCollectionKey(value).
  4. For each element e of S.[[SetData]], do
    1. If e is not empty and SameValue(e, value) is true, return true.
  5. Return false.

24.2.4.9 Set.prototype.intersection ( other )

This method performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[SetData]]).
  3. Let otherRec be ? GetSetRecord(other).
  4. Let resultSetData be a new empty List.
  5. If SetDataSize(O.[[SetData]]) ≤ otherRec.[[Size]], then
    1. Let thisSize be the number of elements in O.[[SetData]].
    2. Let index be 0.
    3. Repeat, while index < thisSize,
      1. Let e be O.[[SetData]][index].
      2. Set index to index + 1.
      3. If e is not empty, then
        1. Let inOther be ToBoolean(? Call(otherRec.[[Has]], otherRec.[[SetObject]], « e »)).
        2. If inOther is true, then
          1. NOTE: It is possible for earlier calls to otherRec.[[Has]] to remove and re-add an element of O.[[SetData]], which can cause the same element to be visited twice during this iteration.
          2. If SetDataHas(resultSetData, e) is false, then
            1. Append e to resultSetData.
        3. NOTE: The number of elements in O.[[SetData]] may have increased during execution of otherRec.[[Has]].
        4. Set thisSize to the number of elements in O.[[SetData]].
  6. Else,
    1. Let keysIter be ? GetIteratorFromMethod(otherRec.[[SetObject]], otherRec.[[Keys]]).
    2. Let next be not-started.
    3. Repeat, while next is not done,
      1. Set next to ? IteratorStepValue(keysIter).
      2. If next is not done, then
        1. Set next to CanonicalizeKeyedCollectionKey(next).
        2. Let inThis be SetDataHas(O.[[SetData]], next).
        3. If inThis is true, then
          1. NOTE: Because other is an arbitrary object, it is possible for its "keys" iterator to produce the same value more than once.
          2. If SetDataHas(resultSetData, next) is false, then
            1. Append next to resultSetData.
  7. Let result be OrdinaryObjectCreate(%Set.prototype%, « [[SetData]] »).
  8. Set result.[[SetData]] to resultSetData.
  9. Return result.

24.2.4.10 Set.prototype.isDisjointFrom ( other )

This method performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[SetData]]).
  3. Let otherRec be ? GetSetRecord(other).
  4. If SetDataSize(O.[[SetData]]) ≤ otherRec.[[Size]], then
    1. Let thisSize be the number of elements in O.[[SetData]].
    2. Let index be 0.
    3. Repeat, while index < thisSize,
      1. Let e be O.[[SetData]][index].
      2. Set index to index + 1.
      3. If e is not empty, then
        1. Let inOther be ToBoolean(? Call(otherRec.[[Has]], otherRec.[[SetObject]], « e »)).
        2. If inOther is true, return false.
        3. NOTE: The number of elements in O.[[SetData]] may have increased during execution of otherRec.[[Has]].
        4. Set thisSize to the number of elements in O.[[SetData]].
  5. Else,
    1. Let keysIter be ? GetIteratorFromMethod(otherRec.[[SetObject]], otherRec.[[Keys]]).
    2. Let next be not-started.
    3. Repeat, while next is not done,
      1. Set next to ? IteratorStepValue(keysIter).
      2. If next is not done, then
        1. If SetDataHas(O.[[SetData]], next) is true, then
          1. Perform ? IteratorClose(keysIter, NormalCompletion(unused)).
          2. Return false.
  6. Return true.

24.2.4.11 Set.prototype.isSubsetOf ( other )

This method performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[SetData]]).
  3. Let otherRec be ? GetSetRecord(other).
  4. If SetDataSize(O.[[SetData]]) > otherRec.[[Size]], return false.
  5. Let thisSize be the number of elements in O.[[SetData]].
  6. Let index be 0.
  7. Repeat, while index < thisSize,
    1. Let e be O.[[SetData]][index].
    2. Set index to index + 1.
    3. If e is not empty, then
      1. Let inOther be ToBoolean(? Call(otherRec.[[Has]], otherRec.[[SetObject]], « e »)).
      2. If inOther is false, return false.
      3. NOTE: The number of elements in O.[[SetData]] may have increased during execution of otherRec.[[Has]].
      4. Set thisSize to the number of elements in O.[[SetData]].
  8. Return true.

24.2.4.12 Set.prototype.isSupersetOf ( other )

This method performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[SetData]]).
  3. Let otherRec be ? GetSetRecord(other).
  4. If SetDataSize(O.[[SetData]]) < otherRec.[[Size]], return false.
  5. Let keysIter be ? GetIteratorFromMethod(otherRec.[[SetObject]], otherRec.[[Keys]]).
  6. Let next be not-started.
  7. Repeat, while next is not done,
    1. Set next to ? IteratorStepValue(keysIter).
    2. If next is not done, then
      1. If SetDataHas(O.[[SetData]], next) is false, then
        1. Perform ? IteratorClose(keysIter, NormalCompletion(unused)).
        2. Return false.
  8. Return true.

24.2.4.13 Set.prototype.keys ( )

The initial value of the "keys" property is %Set.prototype.values%, defined in 24.2.4.17.

Note

For iteration purposes, a Set appears similar to a Map where each entry has the same value for its key and value.

24.2.4.14 get Set.prototype.size

Set.prototype.size is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let S be the this value.
  2. Perform ? RequireInternalSlot(S, [[SetData]]).
  3. Let size be SetDataSize(S.[[SetData]]).
  4. Return 𝔽(size).

24.2.4.15 Set.prototype.symmetricDifference ( other )

This method performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[SetData]]).
  3. Let otherRec be ? GetSetRecord(other).
  4. Let keysIter be ? GetIteratorFromMethod(otherRec.[[SetObject]], otherRec.[[Keys]]).
  5. Let resultSetData be a copy of O.[[SetData]].
  6. Let next be not-started.
  7. Repeat, while next is not done,
    1. Set next to ? IteratorStepValue(keysIter).
    2. If next is not done, then
      1. Set next to CanonicalizeKeyedCollectionKey(next).
      2. Let resultIndex be SetDataIndex(resultSetData, next).
      3. If resultIndex is not-found, let alreadyInResult be false; otherwise let alreadyInResult be true.
      4. If SetDataHas(O.[[SetData]], next) is true, then
        1. If alreadyInResult is true, set resultSetData[resultIndex] to empty.
      5. Else,
        1. If alreadyInResult is false, append next to resultSetData.
  8. Let result be OrdinaryObjectCreate(%Set.prototype%, « [[SetData]] »).
  9. Set result.[[SetData]] to resultSetData.
  10. Return result.

24.2.4.16 Set.prototype.union ( other )

This method performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[SetData]]).
  3. Let otherRec be ? GetSetRecord(other).
  4. Let keysIter be ? GetIteratorFromMethod(otherRec.[[SetObject]], otherRec.[[Keys]]).
  5. Let resultSetData be a copy of O.[[SetData]].
  6. Let next be not-started.
  7. Repeat, while next is not done,
    1. Set next to ? IteratorStepValue(keysIter).
    2. If next is not done, then
      1. Set next to CanonicalizeKeyedCollectionKey(next).
      2. If SetDataHas(resultSetData, next) is false, then
        1. Append next to resultSetData.
  8. Let result be OrdinaryObjectCreate(%Set.prototype%, « [[SetData]] »).
  9. Set result.[[SetData]] to resultSetData.
  10. Return result.

24.2.4.17 Set.prototype.values ( )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Return ? CreateSetIterator(S, value).

24.2.4.18 Set.prototype [ %Symbol.iterator% ] ( )

The initial value of the %Symbol.iterator% property is %Set.prototype.values%, defined in 24.2.4.17.

24.2.4.19 Set.prototype [ %Symbol.toStringTag% ]

The initial value of the %Symbol.toStringTag% property is the String value "Set".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

24.2.5 Properties of Set Instances

Set instances are ordinary objects that inherit properties from the Set prototype object. Set instances also have a [[SetData]] internal slot.

24.2.6 Set Iterator Objects

A Set Iterator is an ordinary object, with the structure defined below, that represents a specific iteration over some specific Set instance object. There is not a named constructor for Set Iterator objects. Instead, Set Iterator objects are created by calling certain methods of Set instance objects.

24.2.6.1 CreateSetIterator ( set, kind )

The abstract operation CreateSetIterator takes arguments set (an ECMAScript language value) and kind (key+value or value) and returns either a normal completion containing a Generator or a throw completion. It is used to create iterator objects for Set methods that return such iterators. It performs the following steps when called:

  1. Perform ? RequireInternalSlot(set, [[SetData]]).
  2. Let closure be a new Abstract Closure with no parameters that captures set and kind and performs the following steps when called:
    1. Let index be 0.
    2. Let entries be set.[[SetData]].
    3. Let numEntries be the number of elements in entries.
    4. Repeat, while index < numEntries,
      1. Let e be entries[index].
      2. Set index to index + 1.
      3. If e is not empty, then
        1. If kind is key+value, then
          1. Let result be CreateArrayFromListe, e »).
          2. Perform ? GeneratorYield(CreateIteratorResultObject(result, false)).
        2. Else,
          1. Assert: kind is value.
          2. Perform ? GeneratorYield(CreateIteratorResultObject(e, false)).
        3. NOTE: The number of elements in entries may have increased while execution of this abstract operation was paused by GeneratorYield.
        4. Set numEntries to the number of elements in entries.
    5. Return NormalCompletion(unused).
  3. Return CreateIteratorFromClosure(closure, "%SetIteratorPrototype%", %SetIteratorPrototype%).

24.2.6.2 The %SetIteratorPrototype% Object

The %SetIteratorPrototype% object:

24.2.6.2.1 %SetIteratorPrototype%.next ( )

  1. Return ? GeneratorResume(this value, empty, "%SetIteratorPrototype%").

24.2.6.2.2 %SetIteratorPrototype% [ %Symbol.toStringTag% ]

The initial value of the %Symbol.toStringTag% property is the String value "Set Iterator".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

24.3 WeakMap Objects

WeakMaps are collections of key/value pairs where the keys are objects and/or symbols and values may be arbitrary ECMAScript language values. A WeakMap may be queried to see if it contains a key/value pair with a specific key, but no mechanism is provided for enumerating the values it holds as keys. In certain conditions, values which are not live are removed as WeakMap keys, as described in 9.9.3.

An implementation may impose an arbitrarily determined latency between the time a key/value pair of a WeakMap becomes inaccessible and the time when the key/value pair is removed from the WeakMap. If this latency was observable to ECMAScript program, it would be a source of indeterminacy that could impact program execution. For that reason, an ECMAScript implementation must not provide any means to observe a key of a WeakMap that does not require the observer to present the observed key.

WeakMaps must be implemented using either hash tables or other mechanisms that, on average, provide access times that are sublinear on the number of key/value pairs in the collection. The data structure used in this specification is only intended to describe the required observable semantics of WeakMaps. It is not intended to be a viable implementation model.

Note

WeakMap and WeakSet are intended to provide mechanisms for dynamically associating state with an object or symbol in a manner that does not “leak” memory resources if, in the absence of the WeakMap or WeakSet instance, the object or symbol otherwise became inaccessible and subject to resource reclamation by the implementation's garbage collection mechanisms. This characteristic can be achieved by using an inverted per-object/symbol mapping of WeakMap or WeakSet instances to keys. Alternatively, each WeakMap or WeakSet instance may internally store its key and value data, but this approach requires coordination between the WeakMap or WeakSet implementation and the garbage collector. The following references describe mechanism that may be useful to implementations of WeakMap and WeakSet:

Barry Hayes. 1997. Ephemerons: a new finalization mechanism. In Proceedings of the 12th ACM SIGPLAN conference on Object-oriented programming, systems, languages, and applications (OOPSLA '97), A. Michael Berman (Ed.). ACM, New York, NY, USA, 176-183, http://doi.acm.org/10.1145/263698.263733.

Alexandra Barros, Roberto Ierusalimschy, Eliminating Cycles in Weak Tables. Journal of Universal Computer Science - J.UCS, vol. 14, no. 21, pp. 3481-3497, 2008, http://www.jucs.org/jucs_14_21/eliminating_cycles_in_weak

24.3.1 The WeakMap Constructor

The WeakMap constructor:

  • is %WeakMap%.
  • is the initial value of the "WeakMap" property of the global object.
  • creates and initializes a new WeakMap when called as a constructor.
  • is not intended to be called as a function and will throw an exception when called in that manner.
  • may be used as the value in an extends clause of a class definition. Subclass constructors that intend to inherit the specified WeakMap behaviour must include a super call to the WeakMap constructor to create and initialize the subclass instance with the internal state necessary to support the WeakMap.prototype built-in methods.

24.3.1.1 WeakMap ( [ iterable ] )

This function performs the following steps when called:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. Let map be ? OrdinaryCreateFromConstructor(NewTarget, "%WeakMap.prototype%", « [[WeakMapData]] »).
  3. Set map.[[WeakMapData]] to a new empty List.
  4. If iterable is either undefined or null, return map.
  5. Let adder be ? Get(map, "set").
  6. If IsCallable(adder) is false, throw a TypeError exception.
  7. Return ? AddEntriesFromIterable(map, iterable, adder).
Note

If the parameter iterable is present, it is expected to be an object that implements a %Symbol.iterator% method that returns an iterator object that produces a two element array-like object whose first element is a value that will be used as a WeakMap key and whose second element is the value to associate with that key.

24.3.2 Properties of the WeakMap Constructor

The WeakMap constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

24.3.2.1 WeakMap.prototype

The initial value of WeakMap.prototype is the WeakMap prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

24.3.3 Properties of the WeakMap Prototype Object

The WeakMap prototype object:

24.3.3.1 WeakMap.prototype.constructor

The initial value of WeakMap.prototype.constructor is %WeakMap%.

24.3.3.2 WeakMap.prototype.delete ( key )

This method performs the following steps when called:

  1. Let M be the this value.
  2. Perform ? RequireInternalSlot(M, [[WeakMapData]]).
  3. If CanBeHeldWeakly(key) is false, return false.
  4. For each Record { [[Key]], [[Value]] } p of M.[[WeakMapData]], do
    1. If p.[[Key]] is not empty and SameValue(p.[[Key]], key) is true, then
      1. Set p.[[Key]] to empty.
      2. Set p.[[Value]] to empty.
      3. Return true.
  5. Return false.
Note

The value empty is used as a specification device to indicate that an entry has been deleted. Actual implementations may take other actions such as physically removing the entry from internal data structures.

24.3.3.3 WeakMap.prototype.get ( key )

This method performs the following steps when called:

  1. Let M be the this value.
  2. Perform ? RequireInternalSlot(M, [[WeakMapData]]).
  3. If CanBeHeldWeakly(key) is false, return undefined.
  4. For each Record { [[Key]], [[Value]] } p of M.[[WeakMapData]], do
    1. If p.[[Key]] is not empty and SameValue(p.[[Key]], key) is true, return p.[[Value]].
  5. Return undefined.

24.3.3.4 WeakMap.prototype.has ( key )

This method performs the following steps when called:

  1. Let M be the this value.
  2. Perform ? RequireInternalSlot(M, [[WeakMapData]]).
  3. If CanBeHeldWeakly(key) is false, return false.
  4. For each Record { [[Key]], [[Value]] } p of M.[[WeakMapData]], do
    1. If p.[[Key]] is not empty and SameValue(p.[[Key]], key) is true, return true.
  5. Return false.

24.3.3.5 WeakMap.prototype.set ( key, value )

This method performs the following steps when called:

  1. Let M be the this value.
  2. Perform ? RequireInternalSlot(M, [[WeakMapData]]).
  3. If CanBeHeldWeakly(key) is false, throw a TypeError exception.
  4. For each Record { [[Key]], [[Value]] } p of M.[[WeakMapData]], do
    1. If p.[[Key]] is not empty and SameValue(p.[[Key]], key) is true, then
      1. Set p.[[Value]] to value.
      2. Return M.
  5. Let p be the Record { [[Key]]: key, [[Value]]: value }.
  6. Append p to M.[[WeakMapData]].
  7. Return M.

24.3.3.6 WeakMap.prototype [ %Symbol.toStringTag% ]

The initial value of the %Symbol.toStringTag% property is the String value "WeakMap".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

24.3.4 Properties of WeakMap Instances

WeakMap instances are ordinary objects that inherit properties from the WeakMap prototype object. WeakMap instances also have a [[WeakMapData]] internal slot.

24.4 WeakSet Objects

WeakSets are collections of objects and/or symbols. A distinct object or symbol may only occur once as an element of a WeakSet's collection. A WeakSet may be queried to see if it contains a specific value, but no mechanism is provided for enumerating the values it holds. In certain conditions, values which are not live are removed as WeakSet elements, as described in 9.9.3.

An implementation may impose an arbitrarily determined latency between the time a value contained in a WeakSet becomes inaccessible and the time when the value is removed from the WeakSet. If this latency was observable to ECMAScript program, it would be a source of indeterminacy that could impact program execution. For that reason, an ECMAScript implementation must not provide any means to determine if a WeakSet contains a particular value that does not require the observer to present the observed value.

WeakSets must be implemented using either hash tables or other mechanisms that, on average, provide access times that are sublinear on the number of elements in the collection. The data structure used in this specification is only intended to describe the required observable semantics of WeakSets. It is not intended to be a viable implementation model.

Note

See the NOTE in 24.3.

24.4.1 The WeakSet Constructor

The WeakSet constructor:

  • is %WeakSet%.
  • is the initial value of the "WeakSet" property of the global object.
  • creates and initializes a new WeakSet when called as a constructor.
  • is not intended to be called as a function and will throw an exception when called in that manner.
  • may be used as the value in an extends clause of a class definition. Subclass constructors that intend to inherit the specified WeakSet behaviour must include a super call to the WeakSet constructor to create and initialize the subclass instance with the internal state necessary to support the WeakSet.prototype built-in methods.

24.4.1.1 WeakSet ( [ iterable ] )

This function performs the following steps when called:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. Let set be ? OrdinaryCreateFromConstructor(NewTarget, "%WeakSet.prototype%", « [[WeakSetData]] »).
  3. Set set.[[WeakSetData]] to a new empty List.
  4. If iterable is either undefined or null, return set.
  5. Let adder be ? Get(set, "add").
  6. If IsCallable(adder) is false, throw a TypeError exception.
  7. Let iteratorRecord be ? GetIterator(iterable, sync).
  8. Repeat,
    1. Let next be ? IteratorStepValue(iteratorRecord).
    2. If next is done, return set.
    3. Let status be Completion(Call(adder, set, « next »)).
    4. IfAbruptCloseIterator(status, iteratorRecord).

24.4.2 Properties of the WeakSet Constructor

The WeakSet constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

24.4.2.1 WeakSet.prototype

The initial value of WeakSet.prototype is the WeakSet prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

24.4.3 Properties of the WeakSet Prototype Object

The WeakSet prototype object:

24.4.3.1 WeakSet.prototype.add ( value )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Perform ? RequireInternalSlot(S, [[WeakSetData]]).
  3. If CanBeHeldWeakly(value) is false, throw a TypeError exception.
  4. For each element e of S.[[WeakSetData]], do
    1. If e is not empty and SameValue(e, value) is true, then
      1. Return S.
  5. Append value to S.[[WeakSetData]].
  6. Return S.

24.4.3.2 WeakSet.prototype.constructor

The initial value of WeakSet.prototype.constructor is %WeakSet%.

24.4.3.3 WeakSet.prototype.delete ( value )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Perform ? RequireInternalSlot(S, [[WeakSetData]]).
  3. If CanBeHeldWeakly(value) is false, return false.
  4. For each element e of S.[[WeakSetData]], do
    1. If e is not empty and SameValue(e, value) is true, then
      1. Replace the element of S.[[WeakSetData]] whose value is e with an element whose value is empty.
      2. Return true.
  5. Return false.
Note

The value empty is used as a specification device to indicate that an entry has been deleted. Actual implementations may take other actions such as physically removing the entry from internal data structures.

24.4.3.4 WeakSet.prototype.has ( value )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Perform ? RequireInternalSlot(S, [[WeakSetData]]).
  3. If CanBeHeldWeakly(value) is false, return false.
  4. For each element e of S.[[WeakSetData]], do
    1. If e is not empty and SameValue(e, value) is true, return true.
  5. Return false.

24.4.3.5 WeakSet.prototype [ %Symbol.toStringTag% ]

The initial value of the %Symbol.toStringTag% property is the String value "WeakSet".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

24.4.4 Properties of WeakSet Instances

WeakSet instances are ordinary objects that inherit properties from the WeakSet prototype object. WeakSet instances also have a [[WeakSetData]] internal slot.

24.5 Abstract Operations for Keyed Collections

24.5.1 CanonicalizeKeyedCollectionKey ( key )

The abstract operation CanonicalizeKeyedCollectionKey takes argument key (an ECMAScript language value) and returns an ECMAScript language value. It performs the following steps when called:

  1. If key is -0𝔽, return +0𝔽.
  2. Return key.

25 Structured Data

25.1 ArrayBuffer Objects

25.1.1 Notation

The descriptions below in this section, 25.4, and 29 use the read-modify-write modification function internal data structure.

A read-modify-write modification function is a mathematical function that is represented as an abstract closure that takes two Lists of byte values as arguments and returns a List of byte values. These abstract closures satisfy all of the following properties:

  • They perform all their algorithm steps atomically.
  • Their individual algorithm steps are not observable.
Note

To aid verifying that a read-modify-write modification function's algorithm steps constitute a pure, mathematical function, the following editorial conventions are recommended:

25.1.2 Fixed-length and Resizable ArrayBuffer Objects

A fixed-length ArrayBuffer is an ArrayBuffer whose byte length cannot change after creation.

A resizable ArrayBuffer is an ArrayBuffer whose byte length may change after creation via calls to ArrayBuffer.prototype.resize ( newLength ).

The kind of ArrayBuffer object that is created depends on the arguments passed to ArrayBuffer ( length [ , options ] ).

25.1.3 Abstract Operations For ArrayBuffer Objects

25.1.3.1 AllocateArrayBuffer ( constructor, byteLength [ , maxByteLength ] )

The abstract operation AllocateArrayBuffer takes arguments constructor (a constructor) and byteLength (a non-negative integer) and optional argument maxByteLength (a non-negative integer or empty) and returns either a normal completion containing an ArrayBuffer or a throw completion. It is used to create an ArrayBuffer. It performs the following steps when called:

  1. Let slots be « [[ArrayBufferData]], [[ArrayBufferByteLength]], [[ArrayBufferDetachKey]] ».
  2. If maxByteLength is present and maxByteLength is not empty, let allocatingResizableBuffer be true; otherwise let allocatingResizableBuffer be false.
  3. If allocatingResizableBuffer is true, then
    1. If byteLength > maxByteLength, throw a RangeError exception.
    2. Append [[ArrayBufferMaxByteLength]] to slots.
  4. Let obj be ? OrdinaryCreateFromConstructor(constructor, "%ArrayBuffer.prototype%", slots).
  5. Let block be ? CreateByteDataBlock(byteLength).
  6. Set obj.[[ArrayBufferData]] to block.
  7. Set obj.[[ArrayBufferByteLength]] to byteLength.
  8. If allocatingResizableBuffer is true, then
    1. If it is not possible to create a Data Block block consisting of maxByteLength bytes, throw a RangeError exception.
    2. NOTE: Resizable ArrayBuffers are designed to be implementable with in-place growth. Implementations may throw if, for example, virtual memory cannot be reserved up front.
    3. Set obj.[[ArrayBufferMaxByteLength]] to maxByteLength.
  9. Return obj.

25.1.3.2 ArrayBufferByteLength ( arrayBuffer, order )

The abstract operation ArrayBufferByteLength takes arguments arrayBuffer (an ArrayBuffer or SharedArrayBuffer) and order (seq-cst or unordered) and returns a non-negative integer. It performs the following steps when called:

  1. If IsSharedArrayBuffer(arrayBuffer) is true and arrayBuffer has an [[ArrayBufferByteLengthData]] internal slot, then
    1. Let bufferByteLengthBlock be arrayBuffer.[[ArrayBufferByteLengthData]].
    2. Let rawLength be GetRawBytesFromSharedBlock(bufferByteLengthBlock, 0, biguint64, true, order).
    3. Let isLittleEndian be the value of the [[LittleEndian]] field of the surrounding agent's Agent Record.
    4. Return (RawBytesToNumeric(biguint64, rawLength, isLittleEndian)).
  2. Assert: IsDetachedBuffer(arrayBuffer) is false.
  3. Return arrayBuffer.[[ArrayBufferByteLength]].

25.1.3.3 ArrayBufferCopyAndDetach ( arrayBuffer, newLength, preserveResizability )

The abstract operation ArrayBufferCopyAndDetach takes arguments arrayBuffer (an ECMAScript language value), newLength (an ECMAScript language value), and preserveResizability (preserve-resizability or fixed-length) and returns either a normal completion containing an ArrayBuffer or a throw completion. It performs the following steps when called:

  1. Perform ? RequireInternalSlot(arrayBuffer, [[ArrayBufferData]]).
  2. If IsSharedArrayBuffer(arrayBuffer) is true, throw a TypeError exception.
  3. If newLength is undefined, then
    1. Let newByteLength be arrayBuffer.[[ArrayBufferByteLength]].
  4. Else,
    1. Let newByteLength be ? ToIndex(newLength).
  5. If IsDetachedBuffer(arrayBuffer) is true, throw a TypeError exception.
  6. If preserveResizability is preserve-resizability and IsFixedLengthArrayBuffer(arrayBuffer) is false, then
    1. Let newMaxByteLength be arrayBuffer.[[ArrayBufferMaxByteLength]].
  7. Else,
    1. Let newMaxByteLength be empty.
  8. If arrayBuffer.[[ArrayBufferDetachKey]] is not undefined, throw a TypeError exception.
  9. Let newBuffer be ? AllocateArrayBuffer(%ArrayBuffer%, newByteLength, newMaxByteLength).
  10. Let copyLength be min(newByteLength, arrayBuffer.[[ArrayBufferByteLength]]).
  11. Let fromBlock be arrayBuffer.[[ArrayBufferData]].
  12. Let toBlock be newBuffer.[[ArrayBufferData]].
  13. Perform CopyDataBlockBytes(toBlock, 0, fromBlock, 0, copyLength).
  14. NOTE: Neither creation of the new Data Block nor copying from the old Data Block are observable. Implementations may implement this method as a zero-copy move or a realloc.
  15. Perform ! DetachArrayBuffer(arrayBuffer).
  16. Return newBuffer.

25.1.3.4 IsDetachedBuffer ( arrayBuffer )

The abstract operation IsDetachedBuffer takes argument arrayBuffer (an ArrayBuffer or a SharedArrayBuffer) and returns a Boolean. It performs the following steps when called:

  1. If arrayBuffer.[[ArrayBufferData]] is null, return true.
  2. Return false.

25.1.3.5 DetachArrayBuffer ( arrayBuffer [ , key ] )

The abstract operation DetachArrayBuffer takes argument arrayBuffer (an ArrayBuffer) and optional argument key (anything) and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:

  1. Assert: IsSharedArrayBuffer(arrayBuffer) is false.
  2. If key is not present, set key to undefined.
  3. If arrayBuffer.[[ArrayBufferDetachKey]] is not key, throw a TypeError exception.
  4. Set arrayBuffer.[[ArrayBufferData]] to null.
  5. Set arrayBuffer.[[ArrayBufferByteLength]] to 0.
  6. Return unused.
Note

Detaching an ArrayBuffer instance disassociates the Data Block used as its backing store from the instance and sets the byte length of the buffer to 0.

25.1.3.6 CloneArrayBuffer ( srcBuffer, srcByteOffset, srcLength )

The abstract operation CloneArrayBuffer takes arguments srcBuffer (an ArrayBuffer or a SharedArrayBuffer), srcByteOffset (a non-negative integer), and srcLength (a non-negative integer) and returns either a normal completion containing an ArrayBuffer or a throw completion. It creates a new ArrayBuffer whose data is a copy of srcBuffer's data over the range starting at srcByteOffset and continuing for srcLength bytes. It performs the following steps when called:

  1. Assert: IsDetachedBuffer(srcBuffer) is false.
  2. Let targetBuffer be ? AllocateArrayBuffer(%ArrayBuffer%, srcLength).
  3. Let srcBlock be srcBuffer.[[ArrayBufferData]].
  4. Let targetBlock be targetBuffer.[[ArrayBufferData]].
  5. Perform CopyDataBlockBytes(targetBlock, 0, srcBlock, srcByteOffset, srcLength).
  6. Return targetBuffer.

25.1.3.7 GetArrayBufferMaxByteLengthOption ( options )

The abstract operation GetArrayBufferMaxByteLengthOption takes argument options (an ECMAScript language value) and returns either a normal completion containing either a non-negative integer or empty, or a throw completion. It performs the following steps when called:

  1. If options is not an Object, return empty.
  2. Let maxByteLength be ? Get(options, "maxByteLength").
  3. If maxByteLength is undefined, return empty.
  4. Return ? ToIndex(maxByteLength).

25.1.3.8 HostResizeArrayBuffer ( buffer, newByteLength )

The host-defined abstract operation HostResizeArrayBuffer takes arguments buffer (an ArrayBuffer) and newByteLength (a non-negative integer) and returns either a normal completion containing either handled or unhandled, or a throw completion. It gives the host an opportunity to perform implementation-defined resizing of buffer. If the host chooses not to handle resizing of buffer, it may return unhandled for the default behaviour.

The implementation of HostResizeArrayBuffer must conform to the following requirements:

  • The abstract operation does not detach buffer.
  • If the abstract operation completes normally with handled, buffer.[[ArrayBufferByteLength]] is newByteLength.

The default implementation of HostResizeArrayBuffer is to return NormalCompletion(unhandled).

25.1.3.9 IsFixedLengthArrayBuffer ( arrayBuffer )

The abstract operation IsFixedLengthArrayBuffer takes argument arrayBuffer (an ArrayBuffer or a SharedArrayBuffer) and returns a Boolean. It performs the following steps when called:

  1. If arrayBuffer has an [[ArrayBufferMaxByteLength]] internal slot, return false.
  2. Return true.

25.1.3.10 IsUnsignedElementType ( type )

The abstract operation IsUnsignedElementType takes argument type (a TypedArray element type) and returns a Boolean. It verifies if the argument type is an unsigned TypedArray element type. It performs the following steps when called:

  1. If type is one of uint8, uint8clamped, uint16, uint32, or biguint64, return true.
  2. Return false.

25.1.3.11 IsUnclampedIntegerElementType ( type )

The abstract operation IsUnclampedIntegerElementType takes argument type (a TypedArray element type) and returns a Boolean. It verifies if the argument type is an Integer TypedArray element type not including uint8clamped. It performs the following steps when called:

  1. If type is one of int8, uint8, int16, uint16, int32, or uint32, return true.
  2. Return false.

25.1.3.12 IsBigIntElementType ( type )

The abstract operation IsBigIntElementType takes argument type (a TypedArray element type) and returns a Boolean. It verifies if the argument type is a BigInt TypedArray element type. It performs the following steps when called:

  1. If type is either biguint64 or bigint64, return true.
  2. Return false.

25.1.3.13 IsNoTearConfiguration ( type, order )

The abstract operation IsNoTearConfiguration takes arguments type (a TypedArray element type) and order (seq-cst, unordered, or init) and returns a Boolean. It performs the following steps when called:

  1. If IsUnclampedIntegerElementType(type) is true, return true.
  2. If IsBigIntElementType(type) is true and order is neither init nor unordered, return true.
  3. Return false.

25.1.3.14 RawBytesToNumeric ( type, rawBytes, isLittleEndian )

The abstract operation RawBytesToNumeric takes arguments type (a TypedArray element type), rawBytes (a List of byte values), and isLittleEndian (a Boolean) and returns a Number or a BigInt. It performs the following steps when called:

  1. Let elementSize be the Element Size value specified in Table 75 for Element Type type.
  2. If isLittleEndian is false, reverse the order of the elements of rawBytes.
  3. If type is float16, then
    1. Let value be the byte elements of rawBytes concatenated and interpreted as a little-endian bit string encoding of an IEEE 754-2019 binary16 value.
    2. If value is a NaN, return NaN.
    3. Return the Number value that corresponds to value.
  4. If type is float32, then
    1. Let value be the byte elements of rawBytes concatenated and interpreted as a little-endian bit string encoding of an IEEE 754-2019 binary32 value.
    2. If value is a NaN, return NaN.
    3. Return the Number value that corresponds to value.
  5. If type is float64, then
    1. Let value be the byte elements of rawBytes concatenated and interpreted as a little-endian bit string encoding of an IEEE 754-2019 binary64 value.
    2. If value is a NaN, return NaN.
    3. Return the Number value that corresponds to value.
  6. If IsUnsignedElementType(type) is true, then
    1. Let intValue be the byte elements of rawBytes concatenated and interpreted as a bit string encoding of an unsigned little-endian binary number.
  7. Else,
    1. Let intValue be the byte elements of rawBytes concatenated and interpreted as a bit string encoding of a binary little-endian two's complement number of bit length elementSize × 8.
  8. If IsBigIntElementType(type) is true, return the BigInt value that corresponds to intValue.
  9. Otherwise, return the Number value that corresponds to intValue.

25.1.3.15 GetRawBytesFromSharedBlock ( block, byteIndex, type, isTypedArray, order )

The abstract operation GetRawBytesFromSharedBlock takes arguments block (a Shared Data Block), byteIndex (a non-negative integer), type (a TypedArray element type), isTypedArray (a Boolean), and order (seq-cst or unordered) and returns a List of byte values. It performs the following steps when called:

  1. Let elementSize be the Element Size value specified in Table 75 for Element Type type.
  2. Let execution be the [[CandidateExecution]] field of the surrounding agent's Agent Record.
  3. Let eventsRecord be the Agent Events Record of execution.[[EventsRecords]] whose [[AgentSignifier]] is AgentSignifier().
  4. If isTypedArray is true and IsNoTearConfiguration(type, order) is true, let noTear be true; otherwise let noTear be false.
  5. Let rawValue be a List of length elementSize whose elements are nondeterministically chosen byte values.
  6. NOTE: In implementations, rawValue is the result of a non-atomic or atomic read instruction on the underlying hardware. The nondeterminism is a semantic prescription of the memory model to describe observable behaviour of hardware with weak consistency.
  7. Let readEvent be ReadSharedMemory { [[Order]]: order, [[NoTear]]: noTear, [[Block]]: block, [[ByteIndex]]: byteIndex, [[ElementSize]]: elementSize }.
  8. Append readEvent to eventsRecord.[[EventList]].
  9. Append Chosen Value Record { [[Event]]: readEvent, [[ChosenValue]]: rawValue } to execution.[[ChosenValues]].
  10. Return rawValue.

25.1.3.16 GetValueFromBuffer ( arrayBuffer, byteIndex, type, isTypedArray, order [ , isLittleEndian ] )

The abstract operation GetValueFromBuffer takes arguments arrayBuffer (an ArrayBuffer or SharedArrayBuffer), byteIndex (a non-negative integer), type (a TypedArray element type), isTypedArray (a Boolean), and order (seq-cst or unordered) and optional argument isLittleEndian (a Boolean) and returns a Number or a BigInt. It performs the following steps when called:

  1. Assert: IsDetachedBuffer(arrayBuffer) is false.
  2. Assert: There are sufficient bytes in arrayBuffer starting at byteIndex to represent a value of type.
  3. Let block be arrayBuffer.[[ArrayBufferData]].
  4. Let elementSize be the Element Size value specified in Table 75 for Element Type type.
  5. If IsSharedArrayBuffer(arrayBuffer) is true, then
    1. Assert: block is a Shared Data Block.
    2. Let rawValue be GetRawBytesFromSharedBlock(block, byteIndex, type, isTypedArray, order).
  6. Else,
    1. Let rawValue be a List whose elements are bytes from block at indices in the interval from byteIndex (inclusive) to byteIndex + elementSize (exclusive).
  7. Assert: The number of elements in rawValue is elementSize.
  8. If isLittleEndian is not present, set isLittleEndian to the value of the [[LittleEndian]] field of the surrounding agent's Agent Record.
  9. Return RawBytesToNumeric(type, rawValue, isLittleEndian).

25.1.3.17 NumericToRawBytes ( type, value, isLittleEndian )

The abstract operation NumericToRawBytes takes arguments type (a TypedArray element type), value (a Number or a BigInt), and isLittleEndian (a Boolean) and returns a List of byte values. It performs the following steps when called:

  1. If type is float16, then
    1. Let rawBytes be a List whose elements are the 2 bytes that are the result of converting value to IEEE 754-2019 binary16 format using roundTiesToEven mode. The bytes are arranged in little endian order. If value is NaN, rawBytes may be set to any implementation chosen IEEE 754-2019 binary16 format NaN encoding. An implementation must always choose the same encoding for each implementation distinguishable NaN value.
  2. Else if type is float32, then
    1. Let rawBytes be a List whose elements are the 4 bytes that are the result of converting value to IEEE 754-2019 binary32 format using roundTiesToEven mode. The bytes are arranged in little endian order. If value is NaN, rawBytes may be set to any implementation chosen IEEE 754-2019 binary32 format NaN encoding. An implementation must always choose the same encoding for each implementation distinguishable NaN value.
  3. Else if type is float64, then
    1. Let rawBytes be a List whose elements are the 8 bytes that are the IEEE 754-2019 binary64 format encoding of value. The bytes are arranged in little endian order. If value is NaN, rawBytes may be set to any implementation chosen IEEE 754-2019 binary64 format NaN encoding. An implementation must always choose the same encoding for each implementation distinguishable NaN value.
  4. Else,
    1. Let n be the Element Size value specified in Table 75 for Element Type type.
    2. Let conversionOperation be the abstract operation named in the Conversion Operation column in Table 75 for Element Type type.
    3. Let intValue be (! conversionOperation(value)).
    4. If intValue ≥ 0, then
      1. Let rawBytes be a List whose elements are the n-byte binary encoding of intValue. The bytes are ordered in little endian order.
    5. Else,
      1. Let rawBytes be a List whose elements are the n-byte binary two's complement encoding of intValue. The bytes are ordered in little endian order.
  5. If isLittleEndian is false, reverse the order of the elements of rawBytes.
  6. Return rawBytes.

25.1.3.18 SetValueInBuffer ( arrayBuffer, byteIndex, type, value, isTypedArray, order [ , isLittleEndian ] )

The abstract operation SetValueInBuffer takes arguments arrayBuffer (an ArrayBuffer or SharedArrayBuffer), byteIndex (a non-negative integer), type (a TypedArray element type), value (a Number or a BigInt), isTypedArray (a Boolean), and order (seq-cst, unordered, or init) and optional argument isLittleEndian (a Boolean) and returns unused. It performs the following steps when called:

  1. Assert: IsDetachedBuffer(arrayBuffer) is false.
  2. Assert: There are sufficient bytes in arrayBuffer starting at byteIndex to represent a value of type.
  3. Assert: value is a BigInt if IsBigIntElementType(type) is true; otherwise, value is a Number.
  4. Let block be arrayBuffer.[[ArrayBufferData]].
  5. Let elementSize be the Element Size value specified in Table 75 for Element Type type.
  6. If isLittleEndian is not present, set isLittleEndian to the value of the [[LittleEndian]] field of the surrounding agent's Agent Record.
  7. Let rawBytes be NumericToRawBytes(type, value, isLittleEndian).
  8. If IsSharedArrayBuffer(arrayBuffer) is true, then
    1. Let execution be the [[CandidateExecution]] field of the surrounding agent's Agent Record.
    2. Let eventsRecord be the Agent Events Record of execution.[[EventsRecords]] whose [[AgentSignifier]] is AgentSignifier().
    3. If isTypedArray is true and IsNoTearConfiguration(type, order) is true, let noTear be true; otherwise let noTear be false.
    4. Append WriteSharedMemory { [[Order]]: order, [[NoTear]]: noTear, [[Block]]: block, [[ByteIndex]]: byteIndex, [[ElementSize]]: elementSize, [[Payload]]: rawBytes } to eventsRecord.[[EventList]].
  9. Else,
    1. Store the individual bytes of rawBytes into block, starting at block[byteIndex].
  10. Return unused.

25.1.3.19 GetModifySetValueInBuffer ( arrayBuffer, byteIndex, type, value, op )

The abstract operation GetModifySetValueInBuffer takes arguments arrayBuffer (an ArrayBuffer or a SharedArrayBuffer), byteIndex (a non-negative integer), type (a TypedArray element type), value (a Number or a BigInt), and op (a read-modify-write modification function) and returns a Number or a BigInt. It performs the following steps when called:

  1. Assert: IsDetachedBuffer(arrayBuffer) is false.
  2. Assert: There are sufficient bytes in arrayBuffer starting at byteIndex to represent a value of type.
  3. Assert: value is a BigInt if IsBigIntElementType(type) is true; otherwise, value is a Number.
  4. Let block be arrayBuffer.[[ArrayBufferData]].
  5. Let elementSize be the Element Size value specified in Table 75 for Element Type type.
  6. Let isLittleEndian be the value of the [[LittleEndian]] field of the surrounding agent's Agent Record.
  7. Let rawBytes be NumericToRawBytes(type, value, isLittleEndian).
  8. If IsSharedArrayBuffer(arrayBuffer) is true, then
    1. Let execution be the [[CandidateExecution]] field of the surrounding agent's Agent Record.
    2. Let eventsRecord be the Agent Events Record of execution.[[EventsRecords]] whose [[AgentSignifier]] is AgentSignifier().
    3. Let rawBytesRead be a List of length elementSize whose elements are nondeterministically chosen byte values.
    4. NOTE: In implementations, rawBytesRead is the result of a load-link, of a load-exclusive, or of an operand of a read-modify-write instruction on the underlying hardware. The nondeterminism is a semantic prescription of the memory model to describe observable behaviour of hardware with weak consistency.
    5. Let rmwEvent be ReadModifyWriteSharedMemory { [[Order]]: seq-cst, [[NoTear]]: true, [[Block]]: block, [[ByteIndex]]: byteIndex, [[ElementSize]]: elementSize, [[Payload]]: rawBytes, [[ModifyOp]]: op }.
    6. Append rmwEvent to eventsRecord.[[EventList]].
    7. Append Chosen Value Record { [[Event]]: rmwEvent, [[ChosenValue]]: rawBytesRead } to execution.[[ChosenValues]].
  9. Else,
    1. Let rawBytesRead be a List of length elementSize whose elements are the sequence of elementSize bytes starting with block[byteIndex].
    2. Let rawBytesModified be op(rawBytesRead, rawBytes).
    3. Store the individual bytes of rawBytesModified into block, starting at block[byteIndex].
  10. Return RawBytesToNumeric(type, rawBytesRead, isLittleEndian).

25.1.4 The ArrayBuffer Constructor

The ArrayBuffer constructor:

  • is %ArrayBuffer%.
  • is the initial value of the "ArrayBuffer" property of the global object.
  • creates and initializes a new ArrayBuffer when called as a constructor.
  • is not intended to be called as a function and will throw an exception when called in that manner.
  • may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified ArrayBuffer behaviour must include a super call to the ArrayBuffer constructor to create and initialize subclass instances with the internal state necessary to support the ArrayBuffer.prototype built-in methods.

25.1.4.1 ArrayBuffer ( length [ , options ] )

This function performs the following steps when called:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. Let byteLength be ? ToIndex(length).
  3. Let requestedMaxByteLength be ? GetArrayBufferMaxByteLengthOption(options).
  4. Return ? AllocateArrayBuffer(NewTarget, byteLength, requestedMaxByteLength).

25.1.5 Properties of the ArrayBuffer Constructor

The ArrayBuffer constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

25.1.5.1 ArrayBuffer.isView ( arg )

This function performs the following steps when called:

  1. If arg is not an Object, return false.
  2. If arg has a [[ViewedArrayBuffer]] internal slot, return true.
  3. Return false.

25.1.5.2 ArrayBuffer.prototype

The initial value of ArrayBuffer.prototype is the ArrayBuffer prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

25.1.5.3 get ArrayBuffer [ %Symbol.species% ]

ArrayBuffer[%Symbol.species%] is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Return the this value.

The value of the "name" property of this function is "get [Symbol.species]".

Note

ArrayBuffer.prototype.slice ( start, end ) normally uses its this value's constructor to create a derived object. However, a subclass constructor may over-ride that default behaviour for the ArrayBuffer.prototype.slice ( start, end ) method by redefining its %Symbol.species% property.

25.1.6 Properties of the ArrayBuffer Prototype Object

The ArrayBuffer prototype object:

  • is %ArrayBuffer.prototype%.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.
  • is an ordinary object.
  • does not have an [[ArrayBufferData]] or [[ArrayBufferByteLength]] internal slot.

25.1.6.1 get ArrayBuffer.prototype.byteLength

ArrayBuffer.prototype.byteLength is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]).
  3. If IsSharedArrayBuffer(O) is true, throw a TypeError exception.
  4. If IsDetachedBuffer(O) is true, return +0𝔽.
  5. Let length be O.[[ArrayBufferByteLength]].
  6. Return 𝔽(length).

25.1.6.2 ArrayBuffer.prototype.constructor

The initial value of ArrayBuffer.prototype.constructor is %ArrayBuffer%.

25.1.6.3 get ArrayBuffer.prototype.detached

ArrayBuffer.prototype.detached is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]).
  3. If IsSharedArrayBuffer(O) is true, throw a TypeError exception.
  4. Return IsDetachedBuffer(O).

25.1.6.4 get ArrayBuffer.prototype.maxByteLength

ArrayBuffer.prototype.maxByteLength is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]).
  3. If IsSharedArrayBuffer(O) is true, throw a TypeError exception.
  4. If IsDetachedBuffer(O) is true, return +0𝔽.
  5. If IsFixedLengthArrayBuffer(O) is true, then
    1. Let length be O.[[ArrayBufferByteLength]].
  6. Else,
    1. Let length be O.[[ArrayBufferMaxByteLength]].
  7. Return 𝔽(length).

25.1.6.5 get ArrayBuffer.prototype.resizable

ArrayBuffer.prototype.resizable is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]).
  3. If IsSharedArrayBuffer(O) is true, throw a TypeError exception.
  4. If IsFixedLengthArrayBuffer(O) is false, return true; otherwise return false.

25.1.6.6 ArrayBuffer.prototype.resize ( newLength )

This method performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[ArrayBufferMaxByteLength]]).
  3. If IsSharedArrayBuffer(O) is true, throw a TypeError exception.
  4. Let newByteLength be ? ToIndex(newLength).
  5. If IsDetachedBuffer(O) is true, throw a TypeError exception.
  6. If newByteLength > O.[[ArrayBufferMaxByteLength]], throw a RangeError exception.
  7. Let hostHandled be ? HostResizeArrayBuffer(O, newByteLength).
  8. If hostHandled is handled, return undefined.
  9. Let oldBlock be O.[[ArrayBufferData]].
  10. Let newBlock be ? CreateByteDataBlock(newByteLength).
  11. Let copyLength be min(newByteLength, O.[[ArrayBufferByteLength]]).
  12. Perform CopyDataBlockBytes(newBlock, 0, oldBlock, 0, copyLength).
  13. NOTE: Neither creation of the new Data Block nor copying from the old Data Block are observable. Implementations may implement this method as in-place growth or shrinkage.
  14. Set O.[[ArrayBufferData]] to newBlock.
  15. Set O.[[ArrayBufferByteLength]] to newByteLength.
  16. Return undefined.

25.1.6.7 ArrayBuffer.prototype.slice ( start, end )

This method performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]).
  3. If IsSharedArrayBuffer(O) is true, throw a TypeError exception.
  4. If IsDetachedBuffer(O) is true, throw a TypeError exception.
  5. Let len be O.[[ArrayBufferByteLength]].
  6. Let relativeStart be ? ToIntegerOrInfinity(start).
  7. If relativeStart = -∞, let first be 0.
  8. Else if relativeStart < 0, let first be max(len + relativeStart, 0).
  9. Else, let first be min(relativeStart, len).
  10. If end is undefined, let relativeEnd be len; else let relativeEnd be ? ToIntegerOrInfinity(end).
  11. If relativeEnd = -∞, let final be 0.
  12. Else if relativeEnd < 0, let final be max(len + relativeEnd, 0).
  13. Else, let final be min(relativeEnd, len).
  14. Let newLen be max(final - first, 0).
  15. Let ctor be ? SpeciesConstructor(O, %ArrayBuffer%).
  16. Let new be ? Construct(ctor, « 𝔽(newLen) »).
  17. Perform ? RequireInternalSlot(new, [[ArrayBufferData]]).
  18. If IsSharedArrayBuffer(new) is true, throw a TypeError exception.
  19. If IsDetachedBuffer(new) is true, throw a TypeError exception.
  20. If SameValue(new, O) is true, throw a TypeError exception.
  21. If new.[[ArrayBufferByteLength]] < newLen, throw a TypeError exception.
  22. NOTE: Side-effects of the above steps may have detached or resized O.
  23. If IsDetachedBuffer(O) is true, throw a TypeError exception.
  24. Let fromBuf be O.[[ArrayBufferData]].
  25. Let toBuf be new.[[ArrayBufferData]].
  26. Let currentLen be O.[[ArrayBufferByteLength]].
  27. If first < currentLen, then
    1. Let count be min(newLen, currentLen - first).
    2. Perform CopyDataBlockBytes(toBuf, 0, fromBuf, first, count).
  28. Return new.

25.1.6.8 ArrayBuffer.prototype.transfer ( [ newLength ] )

This method performs the following steps when called:

  1. Let O be the this value.
  2. Return ? ArrayBufferCopyAndDetach(O, newLength, preserve-resizability).

25.1.6.9 ArrayBuffer.prototype.transferToFixedLength ( [ newLength ] )

This method performs the following steps when called:

  1. Let O be the this value.
  2. Return ? ArrayBufferCopyAndDetach(O, newLength, fixed-length).

25.1.6.10 ArrayBuffer.prototype [ %Symbol.toStringTag% ]

The initial value of the %Symbol.toStringTag% property is the String value "ArrayBuffer".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

25.1.7 Properties of ArrayBuffer Instances

ArrayBuffer instances inherit properties from the ArrayBuffer prototype object. ArrayBuffer instances each have an [[ArrayBufferData]] internal slot, an [[ArrayBufferByteLength]] internal slot, and an [[ArrayBufferDetachKey]] internal slot. ArrayBuffer instances which are resizable each have an [[ArrayBufferMaxByteLength]] internal slot.

ArrayBuffer instances whose [[ArrayBufferData]] is null are considered to be detached and all operators to access or modify data contained in the ArrayBuffer instance will fail.

ArrayBuffer instances whose [[ArrayBufferDetachKey]] is set to a value other than undefined need to have all DetachArrayBuffer calls passing that same "detach key" as an argument, otherwise a TypeError will result. This internal slot is only ever set by certain embedding environments, not by algorithms in this specification.

25.1.8 Resizable ArrayBuffer Guidelines

Note 1

The following are guidelines for ECMAScript programmers working with resizable ArrayBuffer.

We recommend that programs be tested in their deployment environments where possible. The amount of available physical memory differs greatly between hardware devices. Similarly, virtual memory subsystems also differ greatly between hardware devices as well as operating systems. An application that runs without out-of-memory errors on a 64-bit desktop web browser could run out of memory on a 32-bit mobile web browser.

When choosing a value for the "maxByteLength" option for resizable ArrayBuffer, we recommend that the smallest possible size for the application be chosen. We recommend that "maxByteLength" does not exceed 1,073,741,824 (230 bytes or 1GiB).

Please note that successfully constructing a resizable ArrayBuffer for a particular maximum size does not guarantee that future resizes will succeed.

Note 2

The following are guidelines for ECMAScript implementers implementing resizable ArrayBuffer.

Resizable ArrayBuffer can be implemented as copying upon resize, as in-place growth via reserving virtual memory up front, or as a combination of both for different values of the constructor's "maxByteLength" option.

If a host is multi-tenanted (i.e. it runs many ECMAScript applications simultaneously), such as a web browser, and its implementations choose to implement in-place growth by reserving virtual memory, we recommend that both 32-bit and 64-bit implementations throw for values of "maxByteLength" ≥ 1GiB to 1.5GiB. This is to reduce the likelihood a single application can exhaust the virtual memory address space and to reduce interoperability risk.

If a host does not have virtual memory, such as those running on embedded devices without an MMU, or if a host only implements resizing by copying, it may accept any Number value for the "maxByteLength" option. However, we recommend a RangeError be thrown if a memory block of the requested size can never be allocated. For example, if the requested size is greater than the maximum amount of usable memory on the device.

25.2 SharedArrayBuffer Objects

25.2.1 Fixed-length and Growable SharedArrayBuffer Objects

A fixed-length SharedArrayBuffer is a SharedArrayBuffer whose byte length cannot change after creation.

A growable SharedArrayBuffer is a SharedArrayBuffer whose byte length may increase after creation via calls to SharedArrayBuffer.prototype.grow ( newLength ).

The kind of SharedArrayBuffer object that is created depends on the arguments passed to SharedArrayBuffer ( length [ , options ] ).

25.2.2 Abstract Operations for SharedArrayBuffer Objects

25.2.2.1 AllocateSharedArrayBuffer ( constructor, byteLength [ , maxByteLength ] )

The abstract operation AllocateSharedArrayBuffer takes arguments constructor (a constructor) and byteLength (a non-negative integer) and optional argument maxByteLength (a non-negative integer or empty) and returns either a normal completion containing a SharedArrayBuffer or a throw completion. It is used to create a SharedArrayBuffer. It performs the following steps when called:

  1. Let slots be « [[ArrayBufferData]] ».
  2. If maxByteLength is present and maxByteLength is not empty, let allocatingGrowableBuffer be true; otherwise let allocatingGrowableBuffer be false.
  3. If allocatingGrowableBuffer is true, then
    1. If byteLength > maxByteLength, throw a RangeError exception.
    2. Append [[ArrayBufferByteLengthData]] and [[ArrayBufferMaxByteLength]] to slots.
  4. Else,
    1. Append [[ArrayBufferByteLength]] to slots.
  5. Let obj be ? OrdinaryCreateFromConstructor(constructor, "%SharedArrayBuffer.prototype%", slots).
  6. If allocatingGrowableBuffer is true, let allocLength be maxByteLength; otherwise let allocLength be byteLength.
  7. Let block be ? CreateSharedByteDataBlock(allocLength).
  8. Set obj.[[ArrayBufferData]] to block.
  9. If allocatingGrowableBuffer is true, then
    1. Assert: byteLengthmaxByteLength.
    2. Let byteLengthBlock be ? CreateSharedByteDataBlock(8).
    3. Perform SetValueInBuffer(byteLengthBlock, 0, biguint64, (byteLength), true, seq-cst).
    4. Set obj.[[ArrayBufferByteLengthData]] to byteLengthBlock.
    5. Set obj.[[ArrayBufferMaxByteLength]] to maxByteLength.
  10. Else,
    1. Set obj.[[ArrayBufferByteLength]] to byteLength.
  11. Return obj.

25.2.2.2 IsSharedArrayBuffer ( obj )

The abstract operation IsSharedArrayBuffer takes argument obj (an ArrayBuffer or a SharedArrayBuffer) and returns a Boolean. It tests whether an object is an ArrayBuffer, a SharedArrayBuffer, or a subtype of either. It performs the following steps when called:

  1. Let bufferData be obj.[[ArrayBufferData]].
  2. If bufferData is null, return false.
  3. If bufferData is a Data Block, return false.
  4. Assert: bufferData is a Shared Data Block.
  5. Return true.

25.2.2.3 HostGrowSharedArrayBuffer ( buffer, newByteLength )

The host-defined abstract operation HostGrowSharedArrayBuffer takes arguments buffer (a SharedArrayBuffer) and newByteLength (a non-negative integer) and returns either a normal completion containing either handled or unhandled, or a throw completion. It gives the host an opportunity to perform implementation-defined growing of buffer. If the host chooses not to handle growing of buffer, it may return unhandled for the default behaviour.

The implementation of HostGrowSharedArrayBuffer must conform to the following requirements:

  • If the abstract operation does not complete normally with unhandled, and newByteLength < the current byte length of the buffer or newByteLength > buffer.[[ArrayBufferMaxByteLength]], throw a RangeError exception.
  • Let isLittleEndian be the value of the [[LittleEndian]] field of the surrounding agent's Agent Record. If the abstract operation completes normally with handled, a WriteSharedMemory or ReadModifyWriteSharedMemory event whose [[Order]] is seq-cst, [[Payload]] is NumericToRawBytes(biguint64, newByteLength, isLittleEndian), [[Block]] is buffer.[[ArrayBufferByteLengthData]], [[ByteIndex]] is 0, and [[ElementSize]] is 8 is added to the surrounding agent's candidate execution such that racing calls to SharedArrayBuffer.prototype.grow are not "lost", i.e. silently do nothing.
Note

The second requirement above is intentionally vague about how or when the current byte length of buffer is read. Because the byte length must be updated via an atomic read-modify-write operation on the underlying hardware, architectures that use load-link/store-conditional or load-exclusive/store-exclusive instruction pairs may wish to keep the paired instructions close in the instruction stream. As such, SharedArrayBuffer.prototype.grow itself does not perform bounds checking on newByteLength before calling HostGrowSharedArrayBuffer, nor is there a requirement on when the current byte length is read.

This is in contrast with HostResizeArrayBuffer, which is guaranteed that the value of newByteLength is ≥ 0 and ≤ buffer.[[ArrayBufferMaxByteLength]].

The default implementation of HostGrowSharedArrayBuffer is to return NormalCompletion(unhandled).

25.2.3 The SharedArrayBuffer Constructor

The SharedArrayBuffer constructor:

  • is %SharedArrayBuffer%.
  • is the initial value of the "SharedArrayBuffer" property of the global object, if that property is present (see below).
  • creates and initializes a new SharedArrayBuffer when called as a constructor.
  • is not intended to be called as a function and will throw an exception when called in that manner.
  • may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified SharedArrayBuffer behaviour must include a super call to the SharedArrayBuffer constructor to create and initialize subclass instances with the internal state necessary to support the SharedArrayBuffer.prototype built-in methods.

Whenever a host does not provide concurrent access to SharedArrayBuffers it may omit the "SharedArrayBuffer" property of the global object.

Note

Unlike an ArrayBuffer, a SharedArrayBuffer cannot become detached, and its internal [[ArrayBufferData]] slot is never null.

25.2.3.1 SharedArrayBuffer ( length [ , options ] )

This function performs the following steps when called:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. Let byteLength be ? ToIndex(length).
  3. Let requestedMaxByteLength be ? GetArrayBufferMaxByteLengthOption(options).
  4. Return ? AllocateSharedArrayBuffer(NewTarget, byteLength, requestedMaxByteLength).

25.2.4 Properties of the SharedArrayBuffer Constructor

The SharedArrayBuffer constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

25.2.4.1 SharedArrayBuffer.prototype

The initial value of SharedArrayBuffer.prototype is the SharedArrayBuffer prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

25.2.4.2 get SharedArrayBuffer [ %Symbol.species% ]

SharedArrayBuffer[%Symbol.species%] is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Return the this value.

The value of the "name" property of this function is "get [Symbol.species]".

25.2.5 Properties of the SharedArrayBuffer Prototype Object

The SharedArrayBuffer prototype object:

  • is %SharedArrayBuffer.prototype%.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.
  • is an ordinary object.
  • does not have an [[ArrayBufferData]] or [[ArrayBufferByteLength]] internal slot.

25.2.5.1 get SharedArrayBuffer.prototype.byteLength

SharedArrayBuffer.prototype.byteLength is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]).
  3. If IsSharedArrayBuffer(O) is false, throw a TypeError exception.
  4. Let length be ArrayBufferByteLength(O, seq-cst).
  5. Return 𝔽(length).

25.2.5.2 SharedArrayBuffer.prototype.constructor

The initial value of SharedArrayBuffer.prototype.constructor is %SharedArrayBuffer%.

25.2.5.3 SharedArrayBuffer.prototype.grow ( newLength )

This method performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[ArrayBufferMaxByteLength]]).
  3. If IsSharedArrayBuffer(O) is false, throw a TypeError exception.
  4. Let newByteLength be ? ToIndex(newLength).
  5. Let hostHandled be ? HostGrowSharedArrayBuffer(O, newByteLength).
  6. If hostHandled is handled, return undefined.
  7. Let isLittleEndian be the value of the [[LittleEndian]] field of the surrounding agent's Agent Record.
  8. Let byteLengthBlock be O.[[ArrayBufferByteLengthData]].
  9. Let currentByteLengthRawBytes be GetRawBytesFromSharedBlock(byteLengthBlock, 0, biguint64, true, seq-cst).
  10. Let newByteLengthRawBytes be NumericToRawBytes(biguint64, (newByteLength), isLittleEndian).
  11. Repeat,
    1. NOTE: This is a compare-and-exchange loop to ensure that parallel, racing grows of the same buffer are totally ordered, are not lost, and do not silently do nothing. The loop exits if it was able to attempt to grow uncontended.
    2. Let currentByteLength be (RawBytesToNumeric(biguint64, currentByteLengthRawBytes, isLittleEndian)).
    3. If newByteLength = currentByteLength, return undefined.
    4. If newByteLength < currentByteLength or newByteLength > O.[[ArrayBufferMaxByteLength]], throw a RangeError exception.
    5. Let byteLengthDelta be newByteLength - currentByteLength.
    6. If it is impossible to create a new Shared Data Block value consisting of byteLengthDelta bytes, throw a RangeError exception.
    7. NOTE: No new Shared Data Block is constructed and used here. The observable behaviour of growable SharedArrayBuffers is specified by allocating a max-sized Shared Data Block at construction time, and this step captures the requirement that implementations that run out of memory must throw a RangeError.
    8. Let readByteLengthRawBytes be AtomicCompareExchangeInSharedBlock(byteLengthBlock, 0, 8, currentByteLengthRawBytes, newByteLengthRawBytes).
    9. If ByteListEqual(readByteLengthRawBytes, currentByteLengthRawBytes) is true, return undefined.
    10. Set currentByteLengthRawBytes to readByteLengthRawBytes.
Note

Spurious failures of the compare-exchange to update the length are prohibited. If the bounds checking for the new length passes and the implementation is not out of memory, a ReadModifyWriteSharedMemory event (i.e. a successful compare-exchange) is always added into the candidate execution.

Parallel calls to SharedArrayBuffer.prototype.grow are totally ordered. For example, consider two racing calls: sab.grow(10) and sab.grow(20). One of the two calls is guaranteed to win the race. The call to sab.grow(10) will never shrink sab even if sab.grow(20) happened first; in that case it will instead throw a RangeError.

25.2.5.4 get SharedArrayBuffer.prototype.growable

SharedArrayBuffer.prototype.growable is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]).
  3. If IsSharedArrayBuffer(O) is false, throw a TypeError exception.
  4. If IsFixedLengthArrayBuffer(O) is false, return true; otherwise return false.

25.2.5.5 get SharedArrayBuffer.prototype.maxByteLength

SharedArrayBuffer.prototype.maxByteLength is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]).
  3. If IsSharedArrayBuffer(O) is false, throw a TypeError exception.
  4. If IsFixedLengthArrayBuffer(O) is true, then
    1. Let length be O.[[ArrayBufferByteLength]].
  5. Else,
    1. Let length be O.[[ArrayBufferMaxByteLength]].
  6. Return 𝔽(length).

25.2.5.6 SharedArrayBuffer.prototype.slice ( start, end )

This method performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[ArrayBufferData]]).
  3. If IsSharedArrayBuffer(O) is false, throw a TypeError exception.
  4. Let len be ArrayBufferByteLength(O, seq-cst).
  5. Let relativeStart be ? ToIntegerOrInfinity(start).
  6. If relativeStart = -∞, let first be 0.
  7. Else if relativeStart < 0, let first be max(len + relativeStart, 0).
  8. Else, let first be min(relativeStart, len).
  9. If end is undefined, let relativeEnd be len; else let relativeEnd be ? ToIntegerOrInfinity(end).
  10. If relativeEnd = -∞, let final be 0.
  11. Else if relativeEnd < 0, let final be max(len + relativeEnd, 0).
  12. Else, let final be min(relativeEnd, len).
  13. Let newLen be max(final - first, 0).
  14. Let ctor be ? SpeciesConstructor(O, %SharedArrayBuffer%).
  15. Let new be ? Construct(ctor, « 𝔽(newLen) »).
  16. Perform ? RequireInternalSlot(new, [[ArrayBufferData]]).
  17. If IsSharedArrayBuffer(new) is false, throw a TypeError exception.
  18. If new.[[ArrayBufferData]] is O.[[ArrayBufferData]], throw a TypeError exception.
  19. If ArrayBufferByteLength(new, seq-cst) < newLen, throw a TypeError exception.
  20. Let fromBuf be O.[[ArrayBufferData]].
  21. Let toBuf be new.[[ArrayBufferData]].
  22. Perform CopyDataBlockBytes(toBuf, 0, fromBuf, first, newLen).
  23. Return new.

25.2.5.7 SharedArrayBuffer.prototype [ %Symbol.toStringTag% ]

The initial value of the %Symbol.toStringTag% property is the String value "SharedArrayBuffer".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

25.2.6 Properties of SharedArrayBuffer Instances

SharedArrayBuffer instances inherit properties from the SharedArrayBuffer prototype object. SharedArrayBuffer instances each have an [[ArrayBufferData]] internal slot. SharedArrayBuffer instances which are not growable each have an [[ArrayBufferByteLength]] internal slot. SharedArrayBuffer instances which are growable each have an [[ArrayBufferByteLengthData]] internal slot and an [[ArrayBufferMaxByteLength]] internal slot.

Note

SharedArrayBuffer instances, unlike ArrayBuffer instances, are never detached.

25.2.7 Growable SharedArrayBuffer Guidelines

Note 1

The following are guidelines for ECMAScript programmers working with growable SharedArrayBuffer.

We recommend that programs be tested in their deployment environments where possible. The amount of available physical memory differ greatly between hardware devices. Similarly, virtual memory subsystems also differ greatly between hardware devices as well as operating systems. An application that runs without out-of-memory errors on a 64-bit desktop web browser could run out of memory on a 32-bit mobile web browser.

When choosing a value for the "maxByteLength" option for growable SharedArrayBuffer, we recommend that the smallest possible size for the application be chosen. We recommend that "maxByteLength" does not exceed 1073741824, or 1GiB.

Please note that successfully constructing a growable SharedArrayBuffer for a particular maximum size does not guarantee that future grows will succeed.

Not all loads of a growable SharedArrayBuffer's length are synchronizing seq-cst loads. Loads of the length that are for bounds-checking of an integer-indexed property access, e.g. u8[idx], are not synchronizing. In general, in the absence of explicit synchronization, one property access being in-bound does not imply a subsequent property access in the same agent is also in-bound. In contrast, explicit loads of the length via the length and byteLength getters on SharedArrayBuffer, %TypedArray%.prototype, and DataView.prototype are synchronizing. Loads of the length that are performed by built-in methods to check if a TypedArray is entirely out-of-bounds are also synchronizing.

Note 2

The following are guidelines for ECMAScript implementers implementing growable SharedArrayBuffer.

We recommend growable SharedArrayBuffer be implemented as in-place growth via reserving virtual memory up front.

Because grow operations can happen in parallel with memory accesses on a growable SharedArrayBuffer, the constraints of the memory model require that even unordered accesses do not "tear" (bits of their values will not be mixed). In practice, this means the underlying data block of a growable SharedArrayBuffer cannot be grown by being copied without stopping the world. We do not recommend stopping the world as an implementation strategy because it introduces a serialization point and is slow.

Grown memory must appear zeroed from the moment of its creation, including to any racy accesses in parallel. This can be accomplished via zero-filled-on-demand virtual memory pages, or careful synchronization if manually zeroing memory.

Integer-indexed property access on TypedArray views of growable SharedArrayBuffers is intended to be optimizable similarly to access on TypedArray views of non-growable SharedArrayBuffers, because integer-indexed property loads on are not synchronizing on the underlying buffer's length (see programmer guidelines above). For example, bounds checks for property accesses may still be hoisted out of loops.

In practice it is difficult to implement growable SharedArrayBuffer by copying on hosts that do not have virtual memory, such as those running on embedded devices without an MMU. Memory usage behaviour of growable SharedArrayBuffers on such hosts may significantly differ from that of hosts with virtual memory. Such hosts should clearly communicate memory usage expectations to users.

25.3 DataView Objects

25.3.1 Abstract Operations For DataView Objects

25.3.1.1 DataView With Buffer Witness Records

A DataView With Buffer Witness Record is a Record value used to encapsulate a DataView along with a cached byte length of the viewed buffer. It is used to help ensure there is a single shared memory read event of the byte length data block when the viewed buffer is a growable SharedArrayBuffers.

DataView With Buffer Witness Records have the fields listed in Table 77.

Table 77: DataView With Buffer Witness Record Fields
Field Name Value Meaning
[[Object]] a DataView The DataView object whose buffer's byte length is loaded.
[[CachedBufferByteLength]] a non-negative integer or detached The byte length of the object's [[ViewedArrayBuffer]] when the Record was created.

25.3.1.2 MakeDataViewWithBufferWitnessRecord ( obj, order )

The abstract operation MakeDataViewWithBufferWitnessRecord takes arguments obj (a DataView) and order (seq-cst or unordered) and returns a DataView With Buffer Witness Record. It performs the following steps when called:

  1. Let buffer be obj.[[ViewedArrayBuffer]].
  2. If IsDetachedBuffer(buffer) is true, then
    1. Let byteLength be detached.
  3. Else,
    1. Let byteLength be ArrayBufferByteLength(buffer, order).
  4. Return the DataView With Buffer Witness Record { [[Object]]: obj, [[CachedBufferByteLength]]: byteLength }.

25.3.1.3 GetViewByteLength ( viewRecord )

The abstract operation GetViewByteLength takes argument viewRecord (a DataView With Buffer Witness Record) and returns a non-negative integer. It performs the following steps when called:

  1. Assert: IsViewOutOfBounds(viewRecord) is false.
  2. Let view be viewRecord.[[Object]].
  3. If view.[[ByteLength]] is not auto, return view.[[ByteLength]].
  4. Assert: IsFixedLengthArrayBuffer(view.[[ViewedArrayBuffer]]) is false.
  5. Let byteOffset be view.[[ByteOffset]].
  6. Let byteLength be viewRecord.[[CachedBufferByteLength]].
  7. Assert: byteLength is not detached.
  8. Return byteLength - byteOffset.

25.3.1.4 IsViewOutOfBounds ( viewRecord )

The abstract operation IsViewOutOfBounds takes argument viewRecord (a DataView With Buffer Witness Record) and returns a Boolean. It performs the following steps when called:

  1. Let view be viewRecord.[[Object]].
  2. Let bufferByteLength be viewRecord.[[CachedBufferByteLength]].
  3. Assert: IsDetachedBuffer(view.[[ViewedArrayBuffer]]) is true if and only if bufferByteLength is detached.
  4. If bufferByteLength is detached, return true.
  5. Let byteOffsetStart be view.[[ByteOffset]].
  6. If view.[[ByteLength]] is auto, then
    1. Let byteOffsetEnd be bufferByteLength.
  7. Else,
    1. Let byteOffsetEnd be byteOffsetStart + view.[[ByteLength]].
  8. If byteOffsetStart > bufferByteLength or byteOffsetEnd > bufferByteLength, return true.
  9. NOTE: 0-length DataViews are not considered out-of-bounds.
  10. Return false.

25.3.1.5 GetViewValue ( view, requestIndex, isLittleEndian, type )

The abstract operation GetViewValue takes arguments view (an ECMAScript language value), requestIndex (an ECMAScript language value), isLittleEndian (an ECMAScript language value), and type (a TypedArray element type) and returns either a normal completion containing either a Number or a BigInt, or a throw completion. It is used by functions on DataView instances to retrieve values from the view's buffer. It performs the following steps when called:

  1. Perform ? RequireInternalSlot(view, [[DataView]]).
  2. Assert: view has a [[ViewedArrayBuffer]] internal slot.
  3. Let getIndex be ? ToIndex(requestIndex).
  4. Set isLittleEndian to ToBoolean(isLittleEndian).
  5. Let viewOffset be view.[[ByteOffset]].
  6. Let viewRecord be MakeDataViewWithBufferWitnessRecord(view, unordered).
  7. NOTE: Bounds checking is not a synchronizing operation when view's backing buffer is a growable SharedArrayBuffer.
  8. If IsViewOutOfBounds(viewRecord) is true, throw a TypeError exception.
  9. Let viewSize be GetViewByteLength(viewRecord).
  10. Let elementSize be the Element Size value specified in Table 75 for Element Type type.
  11. If getIndex + elementSize > viewSize, throw a RangeError exception.
  12. Let bufferIndex be getIndex + viewOffset.
  13. Return GetValueFromBuffer(view.[[ViewedArrayBuffer]], bufferIndex, type, false, unordered, isLittleEndian).

25.3.1.6 SetViewValue ( view, requestIndex, isLittleEndian, type, value )

The abstract operation SetViewValue takes arguments view (an ECMAScript language value), requestIndex (an ECMAScript language value), isLittleEndian (an ECMAScript language value), type (a TypedArray element type), and value (an ECMAScript language value) and returns either a normal completion containing undefined or a throw completion. It is used by functions on DataView instances to store values into the view's buffer. It performs the following steps when called:

  1. Perform ? RequireInternalSlot(view, [[DataView]]).
  2. Assert: view has a [[ViewedArrayBuffer]] internal slot.
  3. Let getIndex be ? ToIndex(requestIndex).
  4. If IsBigIntElementType(type) is true, let numberValue be ? ToBigInt(value).
  5. Otherwise, let numberValue be ? ToNumber(value).
  6. Set isLittleEndian to ToBoolean(isLittleEndian).
  7. Let viewOffset be view.[[ByteOffset]].
  8. Let viewRecord be MakeDataViewWithBufferWitnessRecord(view, unordered).
  9. NOTE: Bounds checking is not a synchronizing operation when view's backing buffer is a growable SharedArrayBuffer.
  10. If IsViewOutOfBounds(viewRecord) is true, throw a TypeError exception.
  11. Let viewSize be GetViewByteLength(viewRecord).
  12. Let elementSize be the Element Size value specified in Table 75 for Element Type type.
  13. If getIndex + elementSize > viewSize, throw a RangeError exception.
  14. Let bufferIndex be getIndex + viewOffset.
  15. Perform SetValueInBuffer(view.[[ViewedArrayBuffer]], bufferIndex, type, numberValue, false, unordered, isLittleEndian).
  16. Return undefined.

25.3.2 The DataView Constructor

The DataView constructor:

  • is %DataView%.
  • is the initial value of the "DataView" property of the global object.
  • creates and initializes a new DataView when called as a constructor.
  • is not intended to be called as a function and will throw an exception when called in that manner.
  • may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified DataView behaviour must include a super call to the DataView constructor to create and initialize subclass instances with the internal state necessary to support the DataView.prototype built-in methods.

25.3.2.1 DataView ( buffer [ , byteOffset [ , byteLength ] ] )

This function performs the following steps when called:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. Perform ? RequireInternalSlot(buffer, [[ArrayBufferData]]).
  3. Let offset be ? ToIndex(byteOffset).
  4. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
  5. Let bufferByteLength be ArrayBufferByteLength(buffer, seq-cst).
  6. If offset > bufferByteLength, throw a RangeError exception.
  7. Let bufferIsFixedLength be IsFixedLengthArrayBuffer(buffer).
  8. If byteLength is undefined, then
    1. If bufferIsFixedLength is true, then
      1. Let viewByteLength be bufferByteLength - offset.
    2. Else,
      1. Let viewByteLength be auto.
  9. Else,
    1. Let viewByteLength be ? ToIndex(byteLength).
    2. If offset + viewByteLength > bufferByteLength, throw a RangeError exception.
  10. Let O be ? OrdinaryCreateFromConstructor(NewTarget, "%DataView.prototype%", « [[DataView]], [[ViewedArrayBuffer]], [[ByteLength]], [[ByteOffset]] »).
  11. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
  12. Set bufferByteLength to ArrayBufferByteLength(buffer, seq-cst).
  13. If offset > bufferByteLength, throw a RangeError exception.
  14. If byteLength is not undefined, then
    1. If offset + viewByteLength > bufferByteLength, throw a RangeError exception.
  15. Set O.[[ViewedArrayBuffer]] to buffer.
  16. Set O.[[ByteLength]] to viewByteLength.
  17. Set O.[[ByteOffset]] to offset.
  18. Return O.

25.3.3 Properties of the DataView Constructor

The DataView constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

25.3.3.1 DataView.prototype

The initial value of DataView.prototype is the DataView prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

25.3.4 Properties of the DataView Prototype Object

The DataView prototype object:

  • is %DataView.prototype%.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.
  • is an ordinary object.
  • does not have a [[DataView]], [[ViewedArrayBuffer]], [[ByteLength]], or [[ByteOffset]] internal slot.

25.3.4.1 get DataView.prototype.buffer

DataView.prototype.buffer is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[DataView]]).
  3. Assert: O has a [[ViewedArrayBuffer]] internal slot.
  4. Let buffer be O.[[ViewedArrayBuffer]].
  5. Return buffer.

25.3.4.2 get DataView.prototype.byteLength

DataView.prototype.byteLength is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[DataView]]).
  3. Assert: O has a [[ViewedArrayBuffer]] internal slot.
  4. Let viewRecord be MakeDataViewWithBufferWitnessRecord(O, seq-cst).
  5. If IsViewOutOfBounds(viewRecord) is true, throw a TypeError exception.
  6. Let size be GetViewByteLength(viewRecord).
  7. Return 𝔽(size).

25.3.4.3 get DataView.prototype.byteOffset

DataView.prototype.byteOffset is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[DataView]]).
  3. Assert: O has a [[ViewedArrayBuffer]] internal slot.
  4. Let viewRecord be MakeDataViewWithBufferWitnessRecord(O, seq-cst).
  5. If IsViewOutOfBounds(viewRecord) is true, throw a TypeError exception.
  6. Let offset be O.[[ByteOffset]].
  7. Return 𝔽(offset).

25.3.4.4 DataView.prototype.constructor

The initial value of DataView.prototype.constructor is %DataView%.

25.3.4.5 DataView.prototype.getBigInt64 ( byteOffset [ , littleEndian ] )

This method performs the following steps when called:

  1. Let view be the this value.
  2. Return ? GetViewValue(view, byteOffset, littleEndian, bigint64).

25.3.4.6 DataView.prototype.getBigUint64 ( byteOffset [ , littleEndian ] )

This method performs the following steps when called:

  1. Let view be the this value.
  2. Return ? GetViewValue(view, byteOffset, littleEndian, biguint64).

25.3.4.7 DataView.prototype.getFloat16 ( byteOffset [ , littleEndian ] )

This method performs the following steps when called:

  1. Let view be the this value.
  2. If littleEndian is not present, set littleEndian to false.
  3. Return ? GetViewValue(view, byteOffset, littleEndian, float16).

25.3.4.8 DataView.prototype.getFloat32 ( byteOffset [ , littleEndian ] )

This method performs the following steps when called:

  1. Let view be the this value.
  2. If littleEndian is not present, set littleEndian to false.
  3. Return ? GetViewValue(view, byteOffset, littleEndian, float32).

25.3.4.9 DataView.prototype.getFloat64 ( byteOffset [ , littleEndian ] )

This method performs the following steps when called:

  1. Let view be the this value.
  2. If littleEndian is not present, set littleEndian to false.
  3. Return ? GetViewValue(view, byteOffset, littleEndian, float64).

25.3.4.10 DataView.prototype.getInt8 ( byteOffset )

This method performs the following steps when called:

  1. Let view be the this value.
  2. Return ? GetViewValue(view, byteOffset, true, int8).

25.3.4.11 DataView.prototype.getInt16 ( byteOffset [ , littleEndian ] )

This method performs the following steps when called:

  1. Let view be the this value.
  2. If littleEndian is not present, set littleEndian to false.
  3. Return ? GetViewValue(view, byteOffset, littleEndian, int16).

25.3.4.12 DataView.prototype.getInt32 ( byteOffset [ , littleEndian ] )

This method performs the following steps when called:

  1. Let view be the this value.
  2. If littleEndian is not present, set littleEndian to false.
  3. Return ? GetViewValue(view, byteOffset, littleEndian, int32).

25.3.4.13 DataView.prototype.getUint8 ( byteOffset )

This method performs the following steps when called:

  1. Let view be the this value.
  2. Return ? GetViewValue(view, byteOffset, true, uint8).

25.3.4.14 DataView.prototype.getUint16 ( byteOffset [ , littleEndian ] )

This method performs the following steps when called:

  1. Let view be the this value.
  2. If littleEndian is not present, set littleEndian to false.
  3. Return ? GetViewValue(view, byteOffset, littleEndian, uint16).

25.3.4.15 DataView.prototype.getUint32 ( byteOffset [ , littleEndian ] )

This method performs the following steps when called:

  1. Let view be the this value.
  2. If littleEndian is not present, set littleEndian to false.
  3. Return ? GetViewValue(view, byteOffset, littleEndian, uint32).

25.3.4.16 DataView.prototype.setBigInt64 ( byteOffset, value [ , littleEndian ] )

This method performs the following steps when called:

  1. Let view be the this value.
  2. Return ? SetViewValue(view, byteOffset, littleEndian, bigint64, value).

25.3.4.17 DataView.prototype.setBigUint64 ( byteOffset, value [ , littleEndian ] )

This method performs the following steps when called:

  1. Let view be the this value.
  2. Return ? SetViewValue(view, byteOffset, littleEndian, biguint64, value).

25.3.4.18 DataView.prototype.setFloat16 ( byteOffset, value [ , littleEndian ] )

This method performs the following steps when called:

  1. Let view be the this value.
  2. If littleEndian is not present, set littleEndian to false.
  3. Return ? SetViewValue(view, byteOffset, littleEndian, float16, value).

25.3.4.19 DataView.prototype.setFloat32 ( byteOffset, value [ , littleEndian ] )

This method performs the following steps when called:

  1. Let view be the this value.
  2. If littleEndian is not present, set littleEndian to false.
  3. Return ? SetViewValue(view, byteOffset, littleEndian, float32, value).

25.3.4.20 DataView.prototype.setFloat64 ( byteOffset, value [ , littleEndian ] )

This method performs the following steps when called:

  1. Let view be the this value.
  2. If littleEndian is not present, set littleEndian to false.
  3. Return ? SetViewValue(view, byteOffset, littleEndian, float64, value).

25.3.4.21 DataView.prototype.setInt8 ( byteOffset, value )

This method performs the following steps when called:

  1. Let view be the this value.
  2. Return ? SetViewValue(view, byteOffset, true, int8, value).

25.3.4.22 DataView.prototype.setInt16 ( byteOffset, value [ , littleEndian ] )

This method performs the following steps when called:

  1. Let view be the this value.
  2. If littleEndian is not present, set littleEndian to false.
  3. Return ? SetViewValue(view, byteOffset, littleEndian, int16, value).

25.3.4.23 DataView.prototype.setInt32 ( byteOffset, value [ , littleEndian ] )

This method performs the following steps when called:

  1. Let view be the this value.
  2. If littleEndian is not present, set littleEndian to false.
  3. Return ? SetViewValue(view, byteOffset, littleEndian, int32, value).

25.3.4.24 DataView.prototype.setUint8 ( byteOffset, value )

This method performs the following steps when called:

  1. Let view be the this value.
  2. Return ? SetViewValue(view, byteOffset, true, uint8, value).

25.3.4.25 DataView.prototype.setUint16 ( byteOffset, value [ , littleEndian ] )

This method performs the following steps when called:

  1. Let view be the this value.
  2. If littleEndian is not present, set littleEndian to false.
  3. Return ? SetViewValue(view, byteOffset, littleEndian, uint16, value).

25.3.4.26 DataView.prototype.setUint32 ( byteOffset, value [ , littleEndian ] )

This method performs the following steps when called:

  1. Let view be the this value.
  2. If littleEndian is not present, set littleEndian to false.
  3. Return ? SetViewValue(view, byteOffset, littleEndian, uint32, value).

25.3.4.27 DataView.prototype [ %Symbol.toStringTag% ]

The initial value of the %Symbol.toStringTag% property is the String value "DataView".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

25.3.5 Properties of DataView Instances

DataView instances are ordinary objects that inherit properties from the DataView prototype object. DataView instances each have [[DataView]], [[ViewedArrayBuffer]], [[ByteLength]], and [[ByteOffset]] internal slots.

Note

The value of the [[DataView]] internal slot is not used within this specification. The simple presence of that internal slot is used within the specification to identify objects created using the DataView constructor.

25.4 The Atomics Object

The Atomics object:

  • is %Atomics%.
  • is the initial value of the "Atomics" property of the global object.
  • is an ordinary object.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.
  • does not have a [[Construct]] internal method; it cannot be used as a constructor with the new operator.
  • does not have a [[Call]] internal method; it cannot be invoked as a function.

The Atomics object provides functions that operate indivisibly (atomically) on shared memory array cells as well as functions that let agents wait for and dispatch primitive events. When used with discipline, the Atomics functions allow multi-agent programs that communicate through shared memory to execute in a well-understood order even on parallel CPUs. The rules that govern shared-memory communication are provided by the memory model, defined below.

Note

For informative guidelines for programming and implementing shared memory in ECMAScript, please see the notes at the end of the memory model section.

25.4.1 Waiter Record

A Waiter Record is a Record value used to denote a particular call to Atomics.wait or Atomics.waitAsync.

A Waiter Record has fields listed in Table 78.

Table 78: Waiter Record Fields
Field Name Value Meaning
[[AgentSignifier]] an agent signifier The agent that called Atomics.wait or Atomics.waitAsync.
[[PromiseCapability]] a PromiseCapability Record or blocking If denoting a call to Atomics.waitAsync, the resulting promise, otherwise blocking.
[[TimeoutTime]] a non-negative extended mathematical value The earliest time by which timeout may be triggered; computed using time values.
[[Result]] "ok" or "timed-out" The return value of the call.

25.4.2 WaiterList Records

A WaiterList Record is used to explain waiting and notification of agents via Atomics.wait, Atomics.waitAsync, and Atomics.notify.

A WaiterList Record has fields listed in Table 79.

Table 79: WaiterList Record Fields
Field Name Value Meaning
[[Waiters]] a List of Waiter Records The calls to Atomics.wait or Atomics.waitAsync that are waiting on the location with which this WaiterList is associated.
[[MostRecentLeaveEvent]] a Synchronize event or empty The event of the most recent leaving of its critical section, or empty if its critical section has never been entered.

There can be multiple Waiter Records in a WaiterList with the same agent signifier.

The agent cluster has a store of WaiterList Records; the store is indexed by (block, i), where block is a Shared Data Block and i a byte offset into the memory of block. WaiterList Records are agent-independent: a lookup in the store of WaiterList Records by (block, i) will result in the same WaiterList Record in any agent in the agent cluster.

Each WaiterList Record has a critical section that controls exclusive access to that WaiterList Record during evaluation. Only a single agent may enter a WaiterList Record's critical section at one time. Entering and leaving a WaiterList Record's critical section is controlled by the abstract operations EnterCriticalSection and LeaveCriticalSection. Operations on a WaiterList Record—adding and removing waiting agents, traversing the list of agents, suspending and notifying agents on the list, setting and retrieving the Synchronize event—may only be performed by agents that have entered the WaiterList Record's critical section.

25.4.3 Abstract Operations for Atomics

25.4.3.1 ValidateIntegerTypedArray ( typedArray, waitable )

The abstract operation ValidateIntegerTypedArray takes arguments typedArray (an ECMAScript language value) and waitable (a Boolean) and returns either a normal completion containing a TypedArray With Buffer Witness Record, or a throw completion. It performs the following steps when called:

  1. Let taRecord be ? ValidateTypedArray(typedArray, unordered).
  2. NOTE: Bounds checking is not a synchronizing operation when typedArray's backing buffer is a growable SharedArrayBuffer.
  3. If waitable is true, then
    1. If typedArray.[[TypedArrayName]] is neither "Int32Array" nor "BigInt64Array", throw a TypeError exception.
  4. Else,
    1. Let type be TypedArrayElementType(typedArray).
    2. If IsUnclampedIntegerElementType(type) is false and IsBigIntElementType(type) is false, throw a TypeError exception.
  5. Return taRecord.

25.4.3.2 ValidateAtomicAccess ( taRecord, requestIndex )

The abstract operation ValidateAtomicAccess takes arguments taRecord (a TypedArray With Buffer Witness Record) and requestIndex (an ECMAScript language value) and returns either a normal completion containing an integer or a throw completion. It performs the following steps when called:

  1. Let length be TypedArrayLength(taRecord).
  2. Let accessIndex be ? ToIndex(requestIndex).
  3. Assert: accessIndex ≥ 0.
  4. If accessIndexlength, throw a RangeError exception.
  5. Let typedArray be taRecord.[[Object]].
  6. Let elementSize be TypedArrayElementSize(typedArray).
  7. Let offset be typedArray.[[ByteOffset]].
  8. Return (accessIndex × elementSize) + offset.

25.4.3.3 ValidateAtomicAccessOnIntegerTypedArray ( typedArray, requestIndex )

The abstract operation ValidateAtomicAccessOnIntegerTypedArray takes arguments typedArray (an ECMAScript language value) and requestIndex (an ECMAScript language value) and returns either a normal completion containing an integer or a throw completion. It performs the following steps when called:

  1. Let taRecord be ? ValidateIntegerTypedArray(typedArray, false).
  2. Return ? ValidateAtomicAccess(taRecord, requestIndex).

25.4.3.4 RevalidateAtomicAccess ( typedArray, byteIndexInBuffer )

The abstract operation RevalidateAtomicAccess takes arguments typedArray (a TypedArray) and byteIndexInBuffer (an integer) and returns either a normal completion containing unused or a throw completion. This operation revalidates the index within the backing buffer for atomic operations after all argument coercions are performed in Atomics methods, as argument coercions can have arbitrary side effects, which could cause the buffer to become out of bounds. This operation does not throw when typedArray's backing buffer is a SharedArrayBuffer. It performs the following steps when called:

  1. Let taRecord be MakeTypedArrayWithBufferWitnessRecord(typedArray, unordered).
  2. NOTE: Bounds checking is not a synchronizing operation when typedArray's backing buffer is a growable SharedArrayBuffer.
  3. If IsTypedArrayOutOfBounds(taRecord) is true, throw a TypeError exception.
  4. Assert: byteIndexInBuffertypedArray.[[ByteOffset]].
  5. If byteIndexInBuffertaRecord.[[CachedBufferByteLength]], throw a RangeError exception.
  6. Return unused.

25.4.3.5 GetWaiterList ( block, i )

The abstract operation GetWaiterList takes arguments block (a Shared Data Block) and i (a non-negative integer that is evenly divisible by 4) and returns a WaiterList Record. It performs the following steps when called:

  1. Assert: i and i + 3 are valid byte offsets within the memory of block.
  2. Return the WaiterList Record that is referenced by the pair (block, i).

25.4.3.6 EnterCriticalSection ( WL )

The abstract operation EnterCriticalSection takes argument WL (a WaiterList Record) and returns unused. It performs the following steps when called:

  1. Assert: The surrounding agent is not in the critical section for any WaiterList Record.
  2. Wait until no agent is in the critical section for WL, then enter the critical section for WL (without allowing any other agent to enter).
  3. If WL.[[MostRecentLeaveEvent]] is not empty, then
    1. NOTE: A WL whose critical section has been entered at least once has a Synchronize event set by LeaveCriticalSection.
    2. Let execution be the [[CandidateExecution]] field of the surrounding agent's Agent Record.
    3. Let eventsRecord be the Agent Events Record of execution.[[EventsRecords]] whose [[AgentSignifier]] is AgentSignifier().
    4. Let enterEvent be a new Synchronize event.
    5. Append enterEvent to eventsRecord.[[EventList]].
    6. Append (WL.[[MostRecentLeaveEvent]], enterEvent) to eventsRecord.[[AgentSynchronizesWith]].
  4. Return unused.

EnterCriticalSection has contention when an agent attempting to enter the critical section must wait for another agent to leave it. When there is no contention, FIFO order of EnterCriticalSection calls is observable. When there is contention, an implementation may choose an arbitrary order but may not cause an agent to wait indefinitely.

25.4.3.7 LeaveCriticalSection ( WL )

The abstract operation LeaveCriticalSection takes argument WL (a WaiterList Record) and returns unused. It performs the following steps when called:

  1. Assert: The surrounding agent is in the critical section for WL.
  2. Let execution be the [[CandidateExecution]] field of the surrounding agent's Agent Record.
  3. Let eventsRecord be the Agent Events Record of execution.[[EventsRecords]] whose [[AgentSignifier]] is AgentSignifier().
  4. Let leaveEvent be a new Synchronize event.
  5. Append leaveEvent to eventsRecord.[[EventList]].
  6. Set WL.[[MostRecentLeaveEvent]] to leaveEvent.
  7. Leave the critical section for WL.
  8. Return unused.

25.4.3.8 AddWaiter ( WL, waiterRecord )

The abstract operation AddWaiter takes arguments WL (a WaiterList Record) and waiterRecord (a Waiter Record) and returns unused. It performs the following steps when called:

  1. Assert: The surrounding agent is in the critical section for WL.
  2. Assert: There is no Waiter Record in WL.[[Waiters]] whose [[PromiseCapability]] field is waiterRecord.[[PromiseCapability]] and whose [[AgentSignifier]] field is waiterRecord.[[AgentSignifier]].
  3. Append waiterRecord to WL.[[Waiters]].
  4. Return unused.

25.4.3.9 RemoveWaiter ( WL, waiterRecord )

The abstract operation RemoveWaiter takes arguments WL (a WaiterList Record) and waiterRecord (a Waiter Record) and returns unused. It performs the following steps when called:

  1. Assert: The surrounding agent is in the critical section for WL.
  2. Assert: WL.[[Waiters]] contains waiterRecord.
  3. Remove waiterRecord from WL.[[Waiters]].
  4. Return unused.

25.4.3.10 RemoveWaiters ( WL, c )

The abstract operation RemoveWaiters takes arguments WL (a WaiterList Record) and c (a non-negative integer or +∞) and returns a List of Waiter Records. It performs the following steps when called:

  1. Assert: The surrounding agent is in the critical section for WL.
  2. Let len be the number of elements in WL.[[Waiters]].
  3. Let n be min(c, len).
  4. Let L be a List whose elements are the first n elements of WL.[[Waiters]].
  5. Remove the first n elements of WL.[[Waiters]].
  6. Return L.

25.4.3.11 SuspendThisAgent ( WL, waiterRecord )

The abstract operation SuspendThisAgent takes arguments WL (a WaiterList Record) and waiterRecord (a Waiter Record) and returns unused. It performs the following steps when called:

  1. Assert: The surrounding agent is in the critical section for WL.
  2. Assert: WL.[[Waiters]] contains waiterRecord.
  3. Let thisAgent be AgentSignifier().
  4. Assert: waiterRecord.[[AgentSignifier]] is thisAgent.
  5. Assert: waiterRecord.[[PromiseCapability]] is blocking.
  6. Assert: AgentCanSuspend() is true.
  7. Perform LeaveCriticalSection(WL) and suspend the surrounding agent until the time is waiterRecord.[[TimeoutTime]], performing the combined operation in such a way that a notification that arrives after the critical section is exited but before the suspension takes effect is not lost. The surrounding agent can only wake from suspension due to a timeout or due to another agent calling NotifyWaiter with arguments WL and thisAgent (i.e. via a call to Atomics.notify).
  8. Perform EnterCriticalSection(WL).
  9. Return unused.

25.4.3.12 NotifyWaiter ( WL, waiterRecord )

The abstract operation NotifyWaiter takes arguments WL (a WaiterList Record) and waiterRecord (a Waiter Record) and returns unused. It performs the following steps when called:

  1. Assert: The surrounding agent is in the critical section for WL.
  2. If waiterRecord.[[PromiseCapability]] is blocking, then
    1. Wake the agent whose signifier is waiterRecord.[[AgentSignifier]] from suspension.
    2. NOTE: This causes the agent to resume execution in SuspendThisAgent.
  3. Else if AgentSignifier() is waiterRecord.[[AgentSignifier]], then
    1. Let promiseCapability be waiterRecord.[[PromiseCapability]].
    2. Perform ! Call(promiseCapability.[[Resolve]], undefined, « waiterRecord.[[Result]] »).
  4. Else,
    1. Perform EnqueueResolveInAgentJob(waiterRecord.[[AgentSignifier]], waiterRecord.[[PromiseCapability]], waiterRecord.[[Result]]).
  5. Return unused.
Note

An agent must not access another agent's promise capability in any capacity beyond passing it to the host.

25.4.3.13 EnqueueResolveInAgentJob ( agentSignifier, promiseCapability, resolution )

The abstract operation EnqueueResolveInAgentJob takes arguments agentSignifier (an agent signifier), promiseCapability (a PromiseCapability Record), and resolution ("ok" or "timed-out") and returns unused. It performs the following steps when called:

  1. Let resolveJob be a new Job Abstract Closure with no parameters that captures agentSignifier, promiseCapability, and resolution and performs the following steps when called:
    1. Assert: AgentSignifier() is agentSignifier.
    2. Perform ! Call(promiseCapability.[[Resolve]], undefined, « resolution »).
    3. Return unused.
  2. Let realmInTargetAgent be ! GetFunctionRealm(promiseCapability.[[Resolve]]).
  3. Assert: agentSignifier is realmInTargetAgent.[[AgentSignifier]].
  4. Perform HostEnqueueGenericJob(resolveJob, realmInTargetAgent).
  5. Return unused.

25.4.3.14 DoWait ( mode, typedArray, index, value, timeout )

The abstract operation DoWait takes arguments mode (sync or async), typedArray (an ECMAScript language value), index (an ECMAScript language value), value (an ECMAScript language value), and timeout (an ECMAScript language value) and returns either a normal completion containing either an Object, "not-equal", "timed-out", or "ok", or a throw completion. It performs the following steps when called:

  1. Let taRecord be ? ValidateIntegerTypedArray(typedArray, true).
  2. Let buffer be taRecord.[[Object]].[[ViewedArrayBuffer]].
  3. If IsSharedArrayBuffer(buffer) is false, throw a TypeError exception.
  4. Let i be ? ValidateAtomicAccess(taRecord, index).
  5. Let arrayTypeName be typedArray.[[TypedArrayName]].
  6. If arrayTypeName is "BigInt64Array", let v be ? ToBigInt64(value).
  7. Else, let v be ? ToInt32(value).
  8. Let q be ? ToNumber(timeout).
  9. If q is either NaN or +∞𝔽, let t be +∞; else if q is -∞𝔽, let t be 0; else let t be max((q), 0).
  10. If mode is sync and AgentCanSuspend() is false, throw a TypeError exception.
  11. Let block be buffer.[[ArrayBufferData]].
  12. Let offset be typedArray.[[ByteOffset]].
  13. Let byteIndexInBuffer be (i × 4) + offset.
  14. Let WL be GetWaiterList(block, byteIndexInBuffer).
  15. If mode is sync, then
    1. Let promiseCapability be blocking.
    2. Let resultObject be undefined.
  16. Else,
    1. Let promiseCapability be ! NewPromiseCapability(%Promise%).
    2. Let resultObject be OrdinaryObjectCreate(%Object.prototype%).
  17. Perform EnterCriticalSection(WL).
  18. Let elementType be TypedArrayElementType(typedArray).
  19. Let w be GetValueFromBuffer(buffer, byteIndexInBuffer, elementType, true, seq-cst).
  20. If vw, then
    1. Perform LeaveCriticalSection(WL).
    2. If mode is sync, return "not-equal".
    3. Perform ! CreateDataPropertyOrThrow(resultObject, "async", false).
    4. Perform ! CreateDataPropertyOrThrow(resultObject, "value", "not-equal").
    5. Return resultObject.
  21. If t = 0 and mode is async, then
    1. NOTE: There is no special handling of synchronous immediate timeouts. Asynchronous immediate timeouts have special handling in order to fail fast and avoid unnecessary Promise jobs.
    2. Perform LeaveCriticalSection(WL).
    3. Perform ! CreateDataPropertyOrThrow(resultObject, "async", false).
    4. Perform ! CreateDataPropertyOrThrow(resultObject, "value", "timed-out").
    5. Return resultObject.
  22. Let thisAgent be AgentSignifier().
  23. Let now be the time value (UTC) identifying the current time.
  24. Let additionalTimeout be an implementation-defined non-negative mathematical value.
  25. Let timeoutTime be (now) + t + additionalTimeout.
  26. NOTE: When t is +∞, timeoutTime is also +∞.
  27. Let waiterRecord be a new Waiter Record { [[AgentSignifier]]: thisAgent, [[PromiseCapability]]: promiseCapability, [[TimeoutTime]]: timeoutTime, [[Result]]: "ok" }.
  28. Perform AddWaiter(WL, waiterRecord).
  29. If mode is sync, then
    1. Perform SuspendThisAgent(WL, waiterRecord).
  30. Else if timeoutTime is finite, then
    1. Perform EnqueueAtomicsWaitAsyncTimeoutJob(WL, waiterRecord).
  31. Perform LeaveCriticalSection(WL).
  32. If mode is sync, return waiterRecord.[[Result]].
  33. Perform ! CreateDataPropertyOrThrow(resultObject, "async", true).
  34. Perform ! CreateDataPropertyOrThrow(resultObject, "value", promiseCapability.[[Promise]]).
  35. Return resultObject.
Note

additionalTimeout allows implementations to pad timeouts as necessary, such as for reducing power consumption or coarsening timer resolution to mitigate timing attacks. This value may differ from call to call of DoWait.

25.4.3.15 EnqueueAtomicsWaitAsyncTimeoutJob ( WL, waiterRecord )

The abstract operation EnqueueAtomicsWaitAsyncTimeoutJob takes arguments WL (a WaiterList Record) and waiterRecord (a Waiter Record) and returns unused. It performs the following steps when called:

  1. Let timeoutJob be a new Job Abstract Closure with no parameters that captures WL and waiterRecord and performs the following steps when called:
    1. Perform EnterCriticalSection(WL).
    2. If WL.[[Waiters]] contains waiterRecord, then
      1. Let timeOfJobExecution be the time value (UTC) identifying the current time.
      2. Assert: (timeOfJobExecution) ≥ waiterRecord.[[TimeoutTime]] (ignoring potential non-monotonicity of time values).
      3. Set waiterRecord.[[Result]] to "timed-out".
      4. Perform RemoveWaiter(WL, waiterRecord).
      5. Perform NotifyWaiter(WL, waiterRecord).
    3. Perform LeaveCriticalSection(WL).
    4. Return unused.
  2. Let now be the time value (UTC) identifying the current time.
  3. Let currentRealm be the current Realm Record.
  4. Perform HostEnqueueTimeoutJob(timeoutJob, currentRealm, 𝔽(waiterRecord.[[TimeoutTime]]) - now).
  5. Return unused.

25.4.3.16 AtomicCompareExchangeInSharedBlock ( block, byteIndexInBuffer, elementSize, expectedBytes, replacementBytes )

The abstract operation AtomicCompareExchangeInSharedBlock takes arguments block (a Shared Data Block), byteIndexInBuffer (an integer), elementSize (a non-negative integer), expectedBytes (a List of byte values), and replacementBytes (a List of byte values) and returns a List of byte values. It performs the following steps when called:

  1. Let execution be the [[CandidateExecution]] field of the surrounding agent's Agent Record.
  2. Let eventsRecord be the Agent Events Record of execution.[[EventsRecords]] whose [[AgentSignifier]] is AgentSignifier().
  3. Let rawBytesRead be a List of length elementSize whose elements are nondeterministically chosen byte values.
  4. NOTE: In implementations, rawBytesRead is the result of a load-link, of a load-exclusive, or of an operand of a read-modify-write instruction on the underlying hardware. The nondeterminism is a semantic prescription of the memory model to describe observable behaviour of hardware with weak consistency.
  5. NOTE: The comparison of the expected value and the read value is performed outside of the read-modify-write modification function to avoid needlessly strong synchronization when the expected value is not equal to the read value.
  6. If ByteListEqual(rawBytesRead, expectedBytes) is true, then
    1. Let second be a new read-modify-write modification function with parameters (oldBytes, newBytes) that captures nothing and performs the following steps atomically when called:
      1. Return newBytes.
    2. Let event be ReadModifyWriteSharedMemory { [[Order]]: seq-cst, [[NoTear]]: true, [[Block]]: block, [[ByteIndex]]: byteIndexInBuffer, [[ElementSize]]: elementSize, [[Payload]]: replacementBytes, [[ModifyOp]]: second }.
  7. Else,
    1. Let event be ReadSharedMemory { [[Order]]: seq-cst, [[NoTear]]: true, [[Block]]: block, [[ByteIndex]]: byteIndexInBuffer, [[ElementSize]]: elementSize }.
  8. Append event to eventsRecord.[[EventList]].
  9. Append Chosen Value Record { [[Event]]: event, [[ChosenValue]]: rawBytesRead } to execution.[[ChosenValues]].
  10. Return rawBytesRead.

25.4.3.17 AtomicReadModifyWrite ( typedArray, index, value, op )

The abstract operation AtomicReadModifyWrite takes arguments typedArray (an ECMAScript language value), index (an ECMAScript language value), value (an ECMAScript language value), and op (a read-modify-write modification function) and returns either a normal completion containing either a Number or a BigInt, or a throw completion. op takes two List of byte values arguments and returns a List of byte values. This operation atomically loads a value, combines it with another value, and stores the combination. It returns the loaded value. It performs the following steps when called:

  1. Let byteIndexInBuffer be ? ValidateAtomicAccessOnIntegerTypedArray(typedArray, index).
  2. If typedArray.[[ContentType]] is bigint, let v be ? ToBigInt(value).
  3. Otherwise, let v be 𝔽(? ToIntegerOrInfinity(value)).
  4. Perform ? RevalidateAtomicAccess(typedArray, byteIndexInBuffer).
  5. Let buffer be typedArray.[[ViewedArrayBuffer]].
  6. Let elementType be TypedArrayElementType(typedArray).
  7. Return GetModifySetValueInBuffer(buffer, byteIndexInBuffer, elementType, v, op).

25.4.3.18 ByteListBitwiseOp ( op, xBytes, yBytes )

The abstract operation ByteListBitwiseOp takes arguments op (&, ^, or |), xBytes (a List of byte values), and yBytes (a List of byte values) and returns a List of byte values. The operation atomically performs a bitwise operation on all byte values of the arguments and returns a List of byte values. It performs the following steps when called:

  1. Assert: xBytes and yBytes have the same number of elements.
  2. Let result be a new empty List.
  3. Let i be 0.
  4. For each element xByte of xBytes, do
    1. Let yByte be yBytes[i].
    2. If op is &, then
      1. Let resultByte be the result of applying the bitwise AND operation to xByte and yByte.
    3. Else if op is ^, then
      1. Let resultByte be the result of applying the bitwise exclusive OR (XOR) operation to xByte and yByte.
    4. Else,
      1. Assert: op is |.
      2. Let resultByte be the result of applying the bitwise inclusive OR operation to xByte and yByte.
    5. Set i to i + 1.
    6. Append resultByte to result.
  5. Return result.

25.4.3.19 ByteListEqual ( xBytes, yBytes )

The abstract operation ByteListEqual takes arguments xBytes (a List of byte values) and yBytes (a List of byte values) and returns a Boolean. It performs the following steps when called:

  1. If xBytes and yBytes do not have the same number of elements, return false.
  2. Let i be 0.
  3. For each element xByte of xBytes, do
    1. Let yByte be yBytes[i].
    2. If xByteyByte, return false.
    3. Set i to i + 1.
  4. Return true.

25.4.4 Atomics.add ( typedArray, index, value )

This function performs the following steps when called:

  1. Let add be a new read-modify-write modification function with parameters (xBytes, yBytes) that captures typedArray and performs the following steps atomically when called:
    1. Let type be TypedArrayElementType(typedArray).
    2. Let isLittleEndian be the value of the [[LittleEndian]] field of the surrounding agent's Agent Record.
    3. Let x be RawBytesToNumeric(type, xBytes, isLittleEndian).
    4. Let y be RawBytesToNumeric(type, yBytes, isLittleEndian).
    5. If x is a Number, then
      1. Let sum be Number::add(x, y).
    6. Else,
      1. Assert: x is a BigInt.
      2. Let sum be BigInt::add(x, y).
    7. Let sumBytes be NumericToRawBytes(type, sum, isLittleEndian).
    8. Assert: sumBytes, xBytes, and yBytes have the same number of elements.
    9. Return sumBytes.
  2. Return ? AtomicReadModifyWrite(typedArray, index, value, add).

25.4.5 Atomics.and ( typedArray, index, value )

This function performs the following steps when called:

  1. Let and be a new read-modify-write modification function with parameters (xBytes, yBytes) that captures nothing and performs the following steps atomically when called:
    1. Return ByteListBitwiseOp(&, xBytes, yBytes).
  2. Return ? AtomicReadModifyWrite(typedArray, index, value, and).

25.4.6 Atomics.compareExchange ( typedArray, index, expectedValue, replacementValue )

This function performs the following steps when called:

  1. Let byteIndexInBuffer be ? ValidateAtomicAccessOnIntegerTypedArray(typedArray, index).
  2. Let buffer be typedArray.[[ViewedArrayBuffer]].
  3. Let block be buffer.[[ArrayBufferData]].
  4. If typedArray.[[ContentType]] is bigint, then
    1. Let expected be ? ToBigInt(expectedValue).
    2. Let replacement be ? ToBigInt(replacementValue).
  5. Else,
    1. Let expected be 𝔽(? ToIntegerOrInfinity(expectedValue)).
    2. Let replacement be 𝔽(? ToIntegerOrInfinity(replacementValue)).
  6. Perform ? RevalidateAtomicAccess(typedArray, byteIndexInBuffer).
  7. Let elementType be TypedArrayElementType(typedArray).
  8. Let elementSize be TypedArrayElementSize(typedArray).
  9. Let isLittleEndian be the value of the [[LittleEndian]] field of the surrounding agent's Agent Record.
  10. Let expectedBytes be NumericToRawBytes(elementType, expected, isLittleEndian).
  11. Let replacementBytes be NumericToRawBytes(elementType, replacement, isLittleEndian).
  12. If IsSharedArrayBuffer(buffer) is true, then
    1. Let rawBytesRead be AtomicCompareExchangeInSharedBlock(block, byteIndexInBuffer, elementSize, expectedBytes, replacementBytes).
  13. Else,
    1. Let rawBytesRead be a List of length elementSize whose elements are the sequence of elementSize bytes starting with block[byteIndexInBuffer].
    2. If ByteListEqual(rawBytesRead, expectedBytes) is true, then
      1. Store the individual bytes of replacementBytes into block, starting at block[byteIndexInBuffer].
  14. Return RawBytesToNumeric(elementType, rawBytesRead, isLittleEndian).

25.4.7 Atomics.exchange ( typedArray, index, value )

This function performs the following steps when called:

  1. Let second be a new read-modify-write modification function with parameters (oldBytes, newBytes) that captures nothing and performs the following steps atomically when called:
    1. Return newBytes.
  2. Return ? AtomicReadModifyWrite(typedArray, index, value, second).

25.4.8 Atomics.isLockFree ( size )

This function performs the following steps when called:

  1. Let n be ? ToIntegerOrInfinity(size).
  2. Let AR be the Agent Record of the surrounding agent.
  3. If n = 1, return AR.[[IsLockFree1]].
  4. If n = 2, return AR.[[IsLockFree2]].
  5. If n = 4, return true.
  6. If n = 8, return AR.[[IsLockFree8]].
  7. Return false.
Note

This function is an optimization primitive. The intuition is that if the atomic step of an atomic primitive (compareExchange, load, store, add, sub, and, or, xor, or exchange) on a datum of size n bytes will be performed without the surrounding agent acquiring a lock outside the n bytes comprising the datum, then Atomics.isLockFree(n) will return true. High-performance algorithms will use this function to determine whether to use locks or atomic operations in critical sections. If an atomic primitive is not lock-free then it is often more efficient for an algorithm to provide its own locking.

Atomics.isLockFree(4) always returns true as that can be supported on all known relevant hardware. Being able to assume this will generally simplify programs.

Regardless of the value returned by this function, all atomic operations are guaranteed to be atomic. For example, they will never have a visible operation take place in the middle of the operation (e.g., "tearing").

25.4.9 Atomics.load ( typedArray, index )

This function performs the following steps when called:

  1. Let byteIndexInBuffer be ? ValidateAtomicAccessOnIntegerTypedArray(typedArray, index).
  2. Perform ? RevalidateAtomicAccess(typedArray, byteIndexInBuffer).
  3. Let buffer be typedArray.[[ViewedArrayBuffer]].
  4. Let elementType be TypedArrayElementType(typedArray).
  5. Return GetValueFromBuffer(buffer, byteIndexInBuffer, elementType, true, seq-cst).

25.4.10 Atomics.or ( typedArray, index, value )

This function performs the following steps when called:

  1. Let or be a new read-modify-write modification function with parameters (xBytes, yBytes) that captures nothing and performs the following steps atomically when called:
    1. Return ByteListBitwiseOp(|, xBytes, yBytes).
  2. Return ? AtomicReadModifyWrite(typedArray, index, value, or).

25.4.11 Atomics.store ( typedArray, index, value )

This function performs the following steps when called:

  1. Let byteIndexInBuffer be ? ValidateAtomicAccessOnIntegerTypedArray(typedArray, index).
  2. If typedArray.[[ContentType]] is bigint, let v be ? ToBigInt(value).
  3. Otherwise, let v be 𝔽(? ToIntegerOrInfinity(value)).
  4. Perform ? RevalidateAtomicAccess(typedArray, byteIndexInBuffer).
  5. Let buffer be typedArray.[[ViewedArrayBuffer]].
  6. Let elementType be TypedArrayElementType(typedArray).
  7. Perform SetValueInBuffer(buffer, byteIndexInBuffer, elementType, v, true, seq-cst).
  8. Return v.

25.4.12 Atomics.sub ( typedArray, index, value )

This function performs the following steps when called:

  1. Let subtract be a new read-modify-write modification function with parameters (xBytes, yBytes) that captures typedArray and performs the following steps atomically when called:
    1. Let type be TypedArrayElementType(typedArray).
    2. Let isLittleEndian be the value of the [[LittleEndian]] field of the surrounding agent's Agent Record.
    3. Let x be RawBytesToNumeric(type, xBytes, isLittleEndian).
    4. Let y be RawBytesToNumeric(type, yBytes, isLittleEndian).
    5. If x is a Number, then
      1. Let difference be Number::subtract(x, y).
    6. Else,
      1. Assert: x is a BigInt.
      2. Let difference be BigInt::subtract(x, y).
    7. Let differenceBytes be NumericToRawBytes(type, difference, isLittleEndian).
    8. Assert: differenceBytes, xBytes, and yBytes have the same number of elements.
    9. Return differenceBytes.
  2. Return ? AtomicReadModifyWrite(typedArray, index, value, subtract).

25.4.13 Atomics.wait ( typedArray, index, value, timeout )

This function puts the surrounding agent in a wait queue and suspends it until notified or until the wait times out, returning a String differentiating those cases.

It performs the following steps when called:

  1. Return ? DoWait(sync, typedArray, index, value, timeout).

25.4.14 Atomics.waitAsync ( typedArray, index, value, timeout )

This function returns a Promise that is resolved when the calling agent is notified or the timeout is reached.

It performs the following steps when called:

  1. Return ? DoWait(async, typedArray, index, value, timeout).

25.4.15 Atomics.notify ( typedArray, index, count )

This function notifies some agents that are sleeping in the wait queue.

It performs the following steps when called:

  1. Let taRecord be ? ValidateIntegerTypedArray(typedArray, true).
  2. Let byteIndexInBuffer be ? ValidateAtomicAccess(taRecord, index).
  3. If count is undefined, then
    1. Let c be +∞.
  4. Else,
    1. Let intCount be ? ToIntegerOrInfinity(count).
    2. Let c be max(intCount, 0).
  5. Let buffer be typedArray.[[ViewedArrayBuffer]].
  6. Let block be buffer.[[ArrayBufferData]].
  7. If IsSharedArrayBuffer(buffer) is false, return +0𝔽.
  8. Let WL be GetWaiterList(block, byteIndexInBuffer).
  9. Perform EnterCriticalSection(WL).
  10. Let S be RemoveWaiters(WL, c).
  11. For each element W of S, do
    1. Perform NotifyWaiter(WL, W).
  12. Perform LeaveCriticalSection(WL).
  13. Let n be the number of elements in S.
  14. Return 𝔽(n).

25.4.16 Atomics.xor ( typedArray, index, value )

This function performs the following steps when called:

  1. Let xor be a new read-modify-write modification function with parameters (xBytes, yBytes) that captures nothing and performs the following steps atomically when called:
    1. Return ByteListBitwiseOp(^, xBytes, yBytes).
  2. Return ? AtomicReadModifyWrite(typedArray, index, value, xor).

25.4.17 Atomics [ %Symbol.toStringTag% ]

The initial value of the %Symbol.toStringTag% property is the String value "Atomics".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

25.5 The JSON Object

The JSON object:

  • is %JSON%.
  • is the initial value of the "JSON" property of the global object.
  • is an ordinary object.
  • contains two functions, parse and stringify, that are used to parse and construct JSON texts.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.
  • does not have a [[Construct]] internal method; it cannot be used as a constructor with the new operator.
  • does not have a [[Call]] internal method; it cannot be invoked as a function.

The JSON Data Interchange Format is defined in ECMA-404. The JSON interchange format used in this specification is exactly that described by ECMA-404. Conforming implementations of JSON.parse and JSON.stringify must support the exact interchange format described in the ECMA-404 specification without any deletions or extensions to the format.

25.5.1 JSON.parse ( text [ , reviver ] )

This function parses a JSON text (a JSON-formatted String) and produces an ECMAScript language value. The JSON format represents literals, arrays, and objects with a syntax similar to the syntax for ECMAScript literals, Array Initializers, and Object Initializers. After parsing, JSON objects are realized as ECMAScript objects. JSON arrays are realized as ECMAScript Array instances. JSON strings, numbers, booleans, and null are realized as ECMAScript Strings, Numbers, Booleans, and null.

The optional reviver parameter is a function that takes two parameters, key and value. It can filter and transform the results. It is called with each of the key/value pairs produced by the parse, and its return value is used instead of the original value. If it returns what it received, the structure is not modified. If it returns undefined then the property is deleted from the result.

  1. Let jsonString be ? ToString(text).
  2. Let unfiltered be ? ParseJSON(jsonString).
  3. If IsCallable(reviver) is true, then
    1. Let root be OrdinaryObjectCreate(%Object.prototype%).
    2. Let rootName be the empty String.
    3. Perform ! CreateDataPropertyOrThrow(root, rootName, unfiltered).
    4. Return ? InternalizeJSONProperty(root, rootName, reviver).
  4. Else,
    1. Return unfiltered.

The "length" property of this function is 2𝔽.

25.5.1.1 ParseJSON ( text )

The abstract operation ParseJSON takes argument text (a String) and returns either a normal completion containing an ECMAScript language value or a throw completion. It performs the following steps when called:

  1. If StringToCodePoints(text) is not a valid JSON text as specified in ECMA-404, throw a SyntaxError exception.
  2. Let scriptString be the string-concatenation of "(", text, and ");".
  3. Let script be ParseText(scriptString, Script).
  4. NOTE: The early error rules defined in 13.2.5.1 have special handling for the above invocation of ParseText.
  5. Assert: script is a Parse Node.
  6. Let result be ! Evaluation of script.
  7. NOTE: The PropertyDefinitionEvaluation semantics defined in 13.2.5.5 have special handling for the above evaluation.
  8. Assert: result is either a String, a Number, a Boolean, an Object that is defined by either an ArrayLiteral or an ObjectLiteral, or null.
  9. Return result.

It is not permitted for a conforming implementation of JSON.parse to extend the JSON grammars. If an implementation wishes to support a modified or extended JSON interchange format it must do so by defining a different parse function.

Note 1

Valid JSON text is a subset of the ECMAScript PrimaryExpression syntax. Step 1 verifies that jsonString conforms to that subset, and step 8 asserts that evaluation returns a value of an appropriate type.

However, because 13.2.5.5 behaves differently during ParseJSON, the same source text can produce different results when evaluated as a PrimaryExpression rather than as JSON. Furthermore, the Early Error for duplicate "__proto__" properties in object literals, which likewise does not apply during ParseJSON, means that not all texts accepted by ParseJSON are valid as a PrimaryExpression, despite matching the grammar.

Note 2

In the case where there are duplicate name Strings within an object, lexically preceding values for the same key shall be overwritten.

25.5.1.2 InternalizeJSONProperty ( holder, name, reviver )

The abstract operation InternalizeJSONProperty takes arguments holder (an Object), name (a String), and reviver (a function object) and returns either a normal completion containing an ECMAScript language value or a throw completion.

Note

This algorithm intentionally does not throw an exception if either [[Delete]] or CreateDataProperty return false.

It performs the following steps when called:

  1. Let val be ? Get(holder, name).
  2. If val is an Object, then
    1. Let isArray be ? IsArray(val).
    2. If isArray is true, then
      1. Let len be ? LengthOfArrayLike(val).
      2. Let I be 0.
      3. Repeat, while I < len,
        1. Let prop be ! ToString(𝔽(I)).
        2. Let newElement be ? InternalizeJSONProperty(val, prop, reviver).
        3. If newElement is undefined, then
          1. Perform ? val.[[Delete]](prop).
        4. Else,
          1. Perform ? CreateDataProperty(val, prop, newElement).
        5. Set I to I + 1.
    3. Else,
      1. Let keys be ? EnumerableOwnProperties(val, key).
      2. For each String P of keys, do
        1. Let newElement be ? InternalizeJSONProperty(val, P, reviver).
        2. If newElement is undefined, then
          1. Perform ? val.[[Delete]](P).
        3. Else,
          1. Perform ? CreateDataProperty(val, P, newElement).
  3. Return ? Call(reviver, holder, « name, val »).

25.5.2 JSON.stringify ( value [ , replacer [ , space ] ] )

This function returns a String in UTF-16 encoded JSON format representing an ECMAScript language value, or undefined. It can take three parameters. The value parameter is an ECMAScript language value, which is usually an object or array, although it can also be a String, Boolean, Number or null. The optional replacer parameter is either a function that alters the way objects and arrays are stringified, or an array of Strings and Numbers that acts as an inclusion list for selecting the object properties that will be stringified. The optional space parameter is a String or Number that allows the result to have white space injected into it to improve human readability.

It performs the following steps when called:

  1. Let stack be a new empty List.
  2. Let indent be the empty String.
  3. Let PropertyList be undefined.
  4. Let ReplacerFunction be undefined.
  5. If replacer is an Object, then
    1. If IsCallable(replacer) is true, then
      1. Set ReplacerFunction to replacer.
    2. Else,
      1. Let isArray be ? IsArray(replacer).
      2. If isArray is true, then
        1. Set PropertyList to a new empty List.
        2. Let len be ? LengthOfArrayLike(replacer).
        3. Let k be 0.
        4. Repeat, while k < len,
          1. Let prop be ! ToString(𝔽(k)).
          2. Let v be ? Get(replacer, prop).
          3. Let item be undefined.
          4. If v is a String, then
            1. Set item to v.
          5. Else if v is a Number, then
            1. Set item to ! ToString(v).
          6. Else if v is an Object, then
            1. If v has a [[StringData]] or [[NumberData]] internal slot, set item to ? ToString(v).
          7. If item is not undefined and PropertyList does not contain item, then
            1. Append item to PropertyList.
          8. Set k to k + 1.
  6. If space is an Object, then
    1. If space has a [[NumberData]] internal slot, then
      1. Set space to ? ToNumber(space).
    2. Else if space has a [[StringData]] internal slot, then
      1. Set space to ? ToString(space).
  7. If space is a Number, then
    1. Let spaceMV be ! ToIntegerOrInfinity(space).
    2. Set spaceMV to min(10, spaceMV).
    3. If spaceMV < 1, let gap be the empty String; otherwise let gap be the String value containing spaceMV occurrences of the code unit 0x0020 (SPACE).
  8. Else if space is a String, then
    1. If the length of space ≤ 10, let gap be space; otherwise let gap be the substring of space from 0 to 10.
  9. Else,
    1. Let gap be the empty String.
  10. Let wrapper be OrdinaryObjectCreate(%Object.prototype%).
  11. Perform ! CreateDataPropertyOrThrow(wrapper, the empty String, value).
  12. Let state be the JSON Serialization Record { [[ReplacerFunction]]: ReplacerFunction, [[Stack]]: stack, [[Indent]]: indent, [[Gap]]: gap, [[PropertyList]]: PropertyList }.
  13. Return ? SerializeJSONProperty(state, the empty String, wrapper).

The "length" property of this function is 3𝔽.

Note 1

JSON structures are allowed to be nested to any depth, but they must be acyclic. If value is or contains a cyclic structure, then this function must throw a TypeError exception. This is an example of a value that cannot be stringified:

a = [];
a[0] = a;
my_text = JSON.stringify(a); // This must throw a TypeError.
Note 2

Symbolic primitive values are rendered as follows:

  • The null value is rendered in JSON text as the String value "null".
  • The undefined value is not rendered.
  • The true value is rendered in JSON text as the String value "true".
  • The false value is rendered in JSON text as the String value "false".
Note 3

String values are wrapped in QUOTATION MARK (") code units. The code units " and \ are escaped with \ prefixes. Control characters code units are replaced with escape sequences \uHHHH, or with the shorter forms, \b (BACKSPACE), \f (FORM FEED), \n (LINE FEED), \r (CARRIAGE RETURN), \t (CHARACTER TABULATION).

Note 4

Finite numbers are stringified as if by calling ToString(number). NaN and Infinity regardless of sign are represented as the String value "null".

Note 5

Values that do not have a JSON representation (such as undefined and functions) do not produce a String. Instead they produce the undefined value. In arrays these values are represented as the String value "null". In objects an unrepresentable value causes the property to be excluded from stringification.

Note 6

An object is rendered as U+007B (LEFT CURLY BRACKET) followed by zero or more properties, separated with a U+002C (COMMA), closed with a U+007D (RIGHT CURLY BRACKET). A property is a quoted String representing the property name, a U+003A (COLON), and then the stringified property value. An array is rendered as an opening U+005B (LEFT SQUARE BRACKET) followed by zero or more values, separated with a U+002C (COMMA), closed with a U+005D (RIGHT SQUARE BRACKET).

25.5.2.1 JSON Serialization Record

A JSON Serialization Record is a Record value used to enable serialization to the JSON format.

JSON Serialization Records have the fields listed in Table 80.

Table 80: JSON Serialization Record Fields
Field Name Value Meaning
[[ReplacerFunction]] a function object or undefined A function that can supply replacement values for object properties (from JSON.stringify's replacer parameter).
[[PropertyList]] either a List of Strings or undefined The names of properties to include when serializing a non-array object (from JSON.stringify's replacer parameter).
[[Gap]] a String The unit of indentation (from JSON.stringify's space parameter).
[[Stack]] a List of Objects The set of nested objects that are in the process of being serialized. Used to detect cyclic structures.
[[Indent]] a String The current indentation.

25.5.2.2 SerializeJSONProperty ( state, key, holder )

The abstract operation SerializeJSONProperty takes arguments state (a JSON Serialization Record), key (a String), and holder (an Object) and returns either a normal completion containing either a String or undefined, or a throw completion. It performs the following steps when called:

  1. Let value be ? Get(holder, key).
  2. If value is an Object or value is a BigInt, then
    1. Let toJSON be ? GetV(value, "toJSON").
    2. If IsCallable(toJSON) is true, then
      1. Set value to ? Call(toJSON, value, « key »).
  3. If state.[[ReplacerFunction]] is not undefined, then
    1. Set value to ? Call(state.[[ReplacerFunction]], holder, « key, value »).
  4. If value is an Object, then
    1. If value has a [[NumberData]] internal slot, then
      1. Set value to ? ToNumber(value).
    2. Else if value has a [[StringData]] internal slot, then
      1. Set value to ? ToString(value).
    3. Else if value has a [[BooleanData]] internal slot, then
      1. Set value to value.[[BooleanData]].
    4. Else if value has a [[BigIntData]] internal slot, then
      1. Set value to value.[[BigIntData]].
  5. If value is null, return "null".
  6. If value is true, return "true".
  7. If value is false, return "false".
  8. If value is a String, return QuoteJSONString(value).
  9. If value is a Number, then
    1. If value is finite, return ! ToString(value).
    2. Return "null".
  10. If value is a BigInt, throw a TypeError exception.
  11. If value is an Object and IsCallable(value) is false, then
    1. Let isArray be ? IsArray(value).
    2. If isArray is true, return ? SerializeJSONArray(state, value).
    3. Return ? SerializeJSONObject(state, value).
  12. Return undefined.

25.5.2.3 QuoteJSONString ( value )

The abstract operation QuoteJSONString takes argument value (a String) and returns a String. It wraps value in 0x0022 (QUOTATION MARK) code units and escapes certain other code units within it. This operation interprets value as a sequence of UTF-16 encoded code points, as described in 6.1.4. It performs the following steps when called:

  1. Let product be the String value consisting solely of the code unit 0x0022 (QUOTATION MARK).
  2. For each code point C of StringToCodePoints(value), do
    1. If C is listed in the “Code Point” column of Table 81, then
      1. Set product to the string-concatenation of product and the escape sequence for C as specified in the “Escape Sequence” column of the corresponding row.
    2. Else if C has a numeric value less than 0x0020 (SPACE) or C has the same numeric value as a leading surrogate or trailing surrogate, then
      1. Let unit be the code unit whose numeric value is the numeric value of C.
      2. Set product to the string-concatenation of product and UnicodeEscape(unit).
    3. Else,
      1. Set product to the string-concatenation of product and UTF16EncodeCodePoint(C).
  3. Set product to the string-concatenation of product and the code unit 0x0022 (QUOTATION MARK).
  4. Return product.
Table 81: JSON Single Character Escape Sequences
Code Point Unicode Character Name Escape Sequence
U+0008 BACKSPACE \b
U+0009 CHARACTER TABULATION \t
U+000A LINE FEED (LF) \n
U+000C FORM FEED (FF) \f
U+000D CARRIAGE RETURN (CR) \r
U+0022 QUOTATION MARK \"
U+005C REVERSE SOLIDUS \\

25.5.2.4 UnicodeEscape ( C )

The abstract operation UnicodeEscape takes argument C (a code unit) and returns a String. It represents C as a Unicode escape sequence. It performs the following steps when called:

  1. Let n be the numeric value of C.
  2. Assert: n ≤ 0xFFFF.
  3. Let hex be the String representation of n, formatted as a lowercase hexadecimal number.
  4. Return the string-concatenation of the code unit 0x005C (REVERSE SOLIDUS), "u", and StringPad(hex, 4, "0", start).

25.5.2.5 SerializeJSONObject ( state, value )

The abstract operation SerializeJSONObject takes arguments state (a JSON Serialization Record) and value (an Object) and returns either a normal completion containing a String or a throw completion. It serializes an object. It performs the following steps when called:

  1. If state.[[Stack]] contains value, throw a TypeError exception because the structure is cyclical.
  2. Append value to state.[[Stack]].
  3. Let stepBack be state.[[Indent]].
  4. Set state.[[Indent]] to the string-concatenation of state.[[Indent]] and state.[[Gap]].
  5. If state.[[PropertyList]] is not undefined, then
    1. Let K be state.[[PropertyList]].
  6. Else,
    1. Let K be ? EnumerableOwnProperties(value, key).
  7. Let partial be a new empty List.
  8. For each element P of K, do
    1. Let strP be ? SerializeJSONProperty(state, P, value).
    2. If strP is not undefined, then
      1. Let member be QuoteJSONString(P).
      2. Set member to the string-concatenation of member and ":".
      3. If state.[[Gap]] is not the empty String, then
        1. Set member to the string-concatenation of member and the code unit 0x0020 (SPACE).
      4. Set member to the string-concatenation of member and strP.
      5. Append member to partial.
  9. If partial is empty, then
    1. Let final be "{}".
  10. Else,
    1. If state.[[Gap]] is the empty String, then
      1. Let properties be the String value formed by concatenating all the element Strings of partial with each adjacent pair of Strings separated with the code unit 0x002C (COMMA). A comma is not inserted either before the first String or after the last String.
      2. Let final be the string-concatenation of "{", properties, and "}".
    2. Else,
      1. Let separator be the string-concatenation of the code unit 0x002C (COMMA), the code unit 0x000A (LINE FEED), and state.[[Indent]].
      2. Let properties be the String value formed by concatenating all the element Strings of partial with each adjacent pair of Strings separated with separator. The separator String is not inserted either before the first String or after the last String.
      3. Let final be the string-concatenation of "{", the code unit 0x000A (LINE FEED), state.[[Indent]], properties, the code unit 0x000A (LINE FEED), stepBack, and "}".
  11. Remove the last element of state.[[Stack]].
  12. Set state.[[Indent]] to stepBack.
  13. Return final.

25.5.2.6 SerializeJSONArray ( state, value )

The abstract operation SerializeJSONArray takes arguments state (a JSON Serialization Record) and value (an ECMAScript language value) and returns either a normal completion containing a String or a throw completion. It serializes an array. It performs the following steps when called:

  1. If state.[[Stack]] contains value, throw a TypeError exception because the structure is cyclical.
  2. Append value to state.[[Stack]].
  3. Let stepBack be state.[[Indent]].
  4. Set state.[[Indent]] to the string-concatenation of state.[[Indent]] and state.[[Gap]].
  5. Let partial be a new empty List.
  6. Let len be ? LengthOfArrayLike(value).
  7. Let index be 0.
  8. Repeat, while index < len,
    1. Let strP be ? SerializeJSONProperty(state, ! ToString(𝔽(index)), value).
    2. If strP is undefined, then
      1. Append "null" to partial.
    3. Else,
      1. Append strP to partial.
    4. Set index to index + 1.
  9. If partial is empty, then
    1. Let final be "[]".
  10. Else,
    1. If state.[[Gap]] is the empty String, then
      1. Let properties be the String value formed by concatenating all the element Strings of partial with each adjacent pair of Strings separated with the code unit 0x002C (COMMA). A comma is not inserted either before the first String or after the last String.
      2. Let final be the string-concatenation of "[", properties, and "]".
    2. Else,
      1. Let separator be the string-concatenation of the code unit 0x002C (COMMA), the code unit 0x000A (LINE FEED), and state.[[Indent]].
      2. Let properties be the String value formed by concatenating all the element Strings of partial with each adjacent pair of Strings separated with separator. The separator String is not inserted either before the first String or after the last String.
      3. Let final be the string-concatenation of "[", the code unit 0x000A (LINE FEED), state.[[Indent]], properties, the code unit 0x000A (LINE FEED), stepBack, and "]".
  11. Remove the last element of state.[[Stack]].
  12. Set state.[[Indent]] to stepBack.
  13. Return final.
Note

The representation of arrays includes only the elements in the interval from +0𝔽 (inclusive) to array.length (exclusive). Properties whose keys are not array indices are excluded from the stringification. An array is stringified as an opening LEFT SQUARE BRACKET, elements separated by COMMA, and a closing RIGHT SQUARE BRACKET.

25.5.3 JSON [ %Symbol.toStringTag% ]

The initial value of the %Symbol.toStringTag% property is the String value "JSON".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

26 Managing Memory

26.1 WeakRef Objects

A WeakRef is an object that is used to refer to a target object or symbol without preserving it from garbage collection. WeakRefs can be dereferenced to allow access to the target value, if the target hasn't been reclaimed by garbage collection.

26.1.1 The WeakRef Constructor

The WeakRef constructor:

  • is %WeakRef%.
  • is the initial value of the "WeakRef" property of the global object.
  • creates and initializes a new WeakRef when called as a constructor.
  • is not intended to be called as a function and will throw an exception when called in that manner.
  • may be used as the value in an extends clause of a class definition. Subclass constructors that intend to inherit the specified WeakRef behaviour must include a super call to the WeakRef constructor to create and initialize the subclass instance with the internal state necessary to support the WeakRef.prototype built-in methods.

26.1.1.1 WeakRef ( target )

This function performs the following steps when called:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. If CanBeHeldWeakly(target) is false, throw a TypeError exception.
  3. Let weakRef be ? OrdinaryCreateFromConstructor(NewTarget, "%WeakRef.prototype%", « [[WeakRefTarget]] »).
  4. Perform AddToKeptObjects(target).
  5. Set weakRef.[[WeakRefTarget]] to target.
  6. Return weakRef.

26.1.2 Properties of the WeakRef Constructor

The WeakRef constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

26.1.2.1 WeakRef.prototype

The initial value of WeakRef.prototype is the WeakRef prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

26.1.3 Properties of the WeakRef Prototype Object

The WeakRef prototype object:

  • is %WeakRef.prototype%.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.
  • is an ordinary object.
  • does not have a [[WeakRefTarget]] internal slot.

26.1.3.1 WeakRef.prototype.constructor

The initial value of WeakRef.prototype.constructor is %WeakRef%.

26.1.3.2 WeakRef.prototype.deref ( )

This method performs the following steps when called:

  1. Let weakRef be the this value.
  2. Perform ? RequireInternalSlot(weakRef, [[WeakRefTarget]]).
  3. Return WeakRefDeref(weakRef).
Note

If the WeakRef returns a target value that is not undefined, then this target value should not be garbage collected until the current execution of ECMAScript code has completed. The AddToKeptObjects operation makes sure read consistency is maintained.

let target = { foo() {} };
let weakRef = new WeakRef(target);

// ... later ...

if (weakRef.deref()) {
  weakRef.deref().foo();
}

In the above example, if the first deref does not evaluate to undefined then the second deref cannot either.

26.1.3.3 WeakRef.prototype [ %Symbol.toStringTag% ]

The initial value of the %Symbol.toStringTag% property is the String value "WeakRef".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

26.1.4 WeakRef Abstract Operations

26.1.4.1 WeakRefDeref ( weakRef )

The abstract operation WeakRefDeref takes argument weakRef (a WeakRef) and returns an ECMAScript language value. It performs the following steps when called:

  1. Let target be weakRef.[[WeakRefTarget]].
  2. If target is not empty, then
    1. Perform AddToKeptObjects(target).
    2. Return target.
  3. Return undefined.
Note

This abstract operation is defined separately from WeakRef.prototype.deref strictly to make it possible to succinctly define liveness.

26.1.5 Properties of WeakRef Instances

WeakRef instances are ordinary objects that inherit properties from the WeakRef prototype object. WeakRef instances also have a [[WeakRefTarget]] internal slot.

26.2 FinalizationRegistry Objects

A FinalizationRegistry is an object that manages registration and unregistration of cleanup operations that are performed when target objects and symbols are garbage collected.

26.2.1 The FinalizationRegistry Constructor

The FinalizationRegistry constructor:

  • is %FinalizationRegistry%.
  • is the initial value of the "FinalizationRegistry" property of the global object.
  • creates and initializes a new FinalizationRegistry when called as a constructor.
  • is not intended to be called as a function and will throw an exception when called in that manner.
  • may be used as the value in an extends clause of a class definition. Subclass constructors that intend to inherit the specified FinalizationRegistry behaviour must include a super call to the FinalizationRegistry constructor to create and initialize the subclass instance with the internal state necessary to support the FinalizationRegistry.prototype built-in methods.

26.2.1.1 FinalizationRegistry ( cleanupCallback )

This function performs the following steps when called:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. If IsCallable(cleanupCallback) is false, throw a TypeError exception.
  3. Let finalizationRegistry be ? OrdinaryCreateFromConstructor(NewTarget, "%FinalizationRegistry.prototype%", « [[Realm]], [[CleanupCallback]], [[Cells]] »).
  4. Let fn be the active function object.
  5. Set finalizationRegistry.[[Realm]] to fn.[[Realm]].
  6. Set finalizationRegistry.[[CleanupCallback]] to HostMakeJobCallback(cleanupCallback).
  7. Set finalizationRegistry.[[Cells]] to a new empty List.
  8. Return finalizationRegistry.

26.2.2 Properties of the FinalizationRegistry Constructor

The FinalizationRegistry constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

26.2.2.1 FinalizationRegistry.prototype

The initial value of FinalizationRegistry.prototype is the FinalizationRegistry prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

26.2.3 Properties of the FinalizationRegistry Prototype Object

The FinalizationRegistry prototype object:

  • is %FinalizationRegistry.prototype%.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.
  • is an ordinary object.
  • does not have [[Cells]] and [[CleanupCallback]] internal slots.

26.2.3.1 FinalizationRegistry.prototype.constructor

The initial value of FinalizationRegistry.prototype.constructor is %FinalizationRegistry%.

26.2.3.2 FinalizationRegistry.prototype.register ( target, heldValue [ , unregisterToken ] )

This method performs the following steps when called:

  1. Let finalizationRegistry be the this value.
  2. Perform ? RequireInternalSlot(finalizationRegistry, [[Cells]]).
  3. If CanBeHeldWeakly(target) is false, throw a TypeError exception.
  4. If SameValue(target, heldValue) is true, throw a TypeError exception.
  5. If CanBeHeldWeakly(unregisterToken) is false, then
    1. If unregisterToken is not undefined, throw a TypeError exception.
    2. Set unregisterToken to empty.
  6. Let cell be the Record { [[WeakRefTarget]]: target, [[HeldValue]]: heldValue, [[UnregisterToken]]: unregisterToken }.
  7. Append cell to finalizationRegistry.[[Cells]].
  8. Return undefined.
Note

Based on the algorithms and definitions in this specification, cell.[[HeldValue]] is live when finalizationRegistry.[[Cells]] contains cell; however, this does not necessarily mean that cell.[[UnregisterToken]] or cell.[[Target]] are live. For example, registering an object with itself as its unregister token would not keep the object alive forever.

26.2.3.3 FinalizationRegistry.prototype.unregister ( unregisterToken )

This method performs the following steps when called:

  1. Let finalizationRegistry be the this value.
  2. Perform ? RequireInternalSlot(finalizationRegistry, [[Cells]]).
  3. If CanBeHeldWeakly(unregisterToken) is false, throw a TypeError exception.
  4. Let removed be false.
  5. For each Record { [[WeakRefTarget]], [[HeldValue]], [[UnregisterToken]] } cell of finalizationRegistry.[[Cells]], do
    1. If cell.[[UnregisterToken]] is not empty and SameValue(cell.[[UnregisterToken]], unregisterToken) is true, then
      1. Remove cell from finalizationRegistry.[[Cells]].
      2. Set removed to true.
  6. Return removed.

26.2.3.4 FinalizationRegistry.prototype [ %Symbol.toStringTag% ]

The initial value of the %Symbol.toStringTag% property is the String value "FinalizationRegistry".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

26.2.4 Properties of FinalizationRegistry Instances

FinalizationRegistry instances are ordinary objects that inherit properties from the FinalizationRegistry prototype object. FinalizationRegistry instances also have [[Cells]] and [[CleanupCallback]] internal slots.

27 Control Abstraction Objects

27.1 Iteration

27.1.1 Common Iteration Interfaces

An interface is a set of property keys whose associated values match a specific specification. Any object that provides all the properties as described by an interface's specification conforms to that interface. An interface is not represented by a distinct object. There may be many separately implemented objects that conform to any interface. An individual object may conform to multiple interfaces.

27.1.1.1 The Iterable Interface

The iterable interface includes the property described in Table 82:

Table 82: Iterable Interface Required Properties
Property Value Requirements
%Symbol.iterator% a function that returns an iterator object The returned object must conform to the iterator interface.

27.1.1.2 The Iterator Interface

An object that implements the iterator interface must include the property in Table 83. Such objects may also implement the properties in Table 84.

Table 83: Iterator Interface Required Properties
Property Value Requirements
"next" a function that returns an IteratorResult object The returned object must conform to the IteratorResult interface. If a previous call to the next method of an iterator has returned an IteratorResult object whose "done" property is true, then all subsequent calls to the next method of that object should also return an IteratorResult object whose "done" property is true. However, this requirement is not enforced.
Note 1

Arguments may be passed to the next function but their interpretation and validity is dependent upon the target iterator. The for-of statement and other common users of iterators do not pass any arguments, so iterator objects that expect to be used in such a manner must be prepared to deal with being called with no arguments.

Table 84: Iterator Interface Optional Properties
Property Value Requirements
"return" a function that returns an IteratorResult object The returned object must conform to the IteratorResult interface. Invoking this method notifies the iterator object that the caller does not intend to make any more next method calls to the iterator. The returned IteratorResult object will typically have a "done" property whose value is true, and a "value" property with the value passed as the argument of the return method. However, this requirement is not enforced.
"throw" a function that returns an IteratorResult object The returned object must conform to the IteratorResult interface. Invoking this method notifies the iterator object that the caller has detected an error condition. The argument may be used to identify the error condition and typically will be an exception object. A typical response is to throw the value passed as the argument. If the method does not throw, the returned IteratorResult object will typically have a "done" property whose value is true.
Note 2

Typically callers of these methods should check for their existence before invoking them. Certain ECMAScript language features including for-of, yield*, and array destructuring call these methods after performing an existence check. Most ECMAScript library functions that accept iterable objects as arguments also conditionally call them.

27.1.1.3 The Async Iterable Interface

The async iterable interface includes the properties described in Table 85:

Table 85: Async Iterable Interface Required Properties
Property Value Requirements
%Symbol.asyncIterator% a function that returns an async iterator object The returned object must conform to the async iterator interface.

27.1.1.4 The Async Iterator Interface

An object that implements the async iterator interface must include the properties in Table 86. Such objects may also implement the properties in Table 87.

Table 86: Async Iterator Interface Required Properties
Property Value Requirements
"next" a function that returns a promise for an IteratorResult object

The returned promise, when fulfilled, must fulfill with an object that conforms to the IteratorResult interface. If a previous call to the next method of an async iterator has returned a promise for an IteratorResult object whose "done" property is true, then all subsequent calls to the next method of that object should also return a promise for an IteratorResult object whose "done" property is true. However, this requirement is not enforced.

Additionally, the IteratorResult object that serves as a fulfillment value should have a "value" property whose value is not a promise (or "thenable"). However, this requirement is also not enforced.

Note 1

Arguments may be passed to the next function but their interpretation and validity is dependent upon the target async iterator. The for-await-of statement and other common users of async iterators do not pass any arguments, so async iterator objects that expect to be used in such a manner must be prepared to deal with being called with no arguments.

Table 87: Async Iterator Interface Optional Properties
Property Value Requirements
"return" a function that returns a promise for an IteratorResult object

The returned promise, when fulfilled, must fulfill with an object that conforms to the IteratorResult interface. Invoking this method notifies the async iterator object that the caller does not intend to make any more next method calls to the async iterator. The returned promise will fulfill with an IteratorResult object which will typically have a "done" property whose value is true, and a "value" property with the value passed as the argument of the return method. However, this requirement is not enforced.

Additionally, the IteratorResult object that serves as a fulfillment value should have a "value" property whose value is not a promise (or "thenable"). If the argument value is used in the typical manner, then if it is a rejected promise, a promise rejected with the same reason should be returned; if it is a fulfilled promise, then its fulfillment value should be used as the "value" property of the returned promise's IteratorResult object fulfillment value. However, these requirements are also not enforced.

"throw" a function that returns a promise for an IteratorResult object

The returned promise, when fulfilled, must fulfill with an object that conforms to the IteratorResult interface. Invoking this method notifies the async iterator object that the caller has detected an error condition. The argument may be used to identify the error condition and typically will be an exception object. A typical response is to return a rejected promise which rejects with the value passed as the argument.

If the returned promise is fulfilled, the IteratorResult object fulfillment value will typically have a "done" property whose value is true. Additionally, it should have a "value" property whose value is not a promise (or "thenable"), but this requirement is not enforced.

Note 2

Typically callers of these methods should check for their existence before invoking them. Certain ECMAScript language features including for-await-of and yield* call these methods after performing an existence check.

27.1.1.5 The IteratorResult Interface

The IteratorResult interface includes the properties listed in Table 88:

Table 88: IteratorResult Interface Properties
Property Value Requirements
"done" a Boolean This is the result status of an iterator next method call. If the end of the iterator was reached "done" is true. If the end was not reached "done" is false and a value is available. If a "done" property (either own or inherited) does not exist, it is considered to have the value false.
"value" an ECMAScript language value If done is false, this is the current iteration element value. If done is true, this is the return value of the iterator, if it supplied one. If the iterator does not have a return value, "value" is undefined. In that case, the "value" property may be absent from the conforming object if it does not inherit an explicit "value" property.

27.1.2 Iterator Helper Objects

An Iterator Helper object is an ordinary object that represents a lazy transformation of some specific source iterator object. There is not a named constructor for Iterator Helper objects. Instead, Iterator Helper objects are created by calling certain methods of Iterator instance objects.

27.1.2.1 The %IteratorHelperPrototype% Object

The %IteratorHelperPrototype% object:

27.1.2.1.1 %IteratorHelperPrototype%.next ( )

  1. Return ? GeneratorResume(this value, undefined, "Iterator Helper").

27.1.2.1.2 %IteratorHelperPrototype%.return ( )

  1. Let O be this value.
  2. Perform ? RequireInternalSlot(O, [[UnderlyingIterator]]).
  3. Assert: O has a [[GeneratorState]] internal slot.
  4. If O.[[GeneratorState]] is suspended-start, then
    1. Set O.[[GeneratorState]] to completed.
    2. NOTE: Once a generator enters the completed state it never leaves it and its associated execution context is never resumed. Any execution state associated with O can be discarded at this point.
    3. Perform ? IteratorClose(O.[[UnderlyingIterator]], NormalCompletion(unused)).
    4. Return CreateIteratorResultObject(undefined, true).
  5. Let C be ReturnCompletion(undefined).
  6. Return ? GeneratorResumeAbrupt(O, C, "Iterator Helper").

27.1.2.1.3 %IteratorHelperPrototype% [ %Symbol.toStringTag% ]

The initial value of the %Symbol.toStringTag% property is the String value "Iterator Helper".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

27.1.3 Iterator Objects

27.1.3.1 The Iterator Constructor

The Iterator constructor:

  • is %Iterator%.
  • is the initial value of the "Iterator" property of the global object.
  • is designed to be subclassable. It may be used as the value of an extends clause of a class definition.

27.1.3.1.1 Iterator ( )

This function performs the following steps when called:

  1. If NewTarget is either undefined or the active function object, throw a TypeError exception.
  2. Return ? OrdinaryCreateFromConstructor(NewTarget, "%Iterator.prototype%").

27.1.3.2 Properties of the Iterator Constructor

The Iterator constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

27.1.3.2.1 Iterator.from ( O )

  1. Let iteratorRecord be ? GetIteratorFlattenable(O, iterate-string-primitives).
  2. Let hasInstance be ? OrdinaryHasInstance(%Iterator%, iteratorRecord.[[Iterator]]).
  3. If hasInstance is true, then
    1. Return iteratorRecord.[[Iterator]].
  4. Let wrapper be OrdinaryObjectCreate(%WrapForValidIteratorPrototype%, « [[Iterated]] »).
  5. Set wrapper.[[Iterated]] to iteratorRecord.
  6. Return wrapper.

27.1.3.2.1.1 The %WrapForValidIteratorPrototype% Object

The %WrapForValidIteratorPrototype% object:

27.1.3.2.1.1.1 %WrapForValidIteratorPrototype%.next ( )

  1. Let O be this value.
  2. Perform ? RequireInternalSlot(O, [[Iterated]]).
  3. Let iteratorRecord be O.[[Iterated]].
  4. Return ? Call(iteratorRecord.[[NextMethod]], iteratorRecord.[[Iterator]]).

27.1.3.2.1.1.2 %WrapForValidIteratorPrototype%.return ( )

  1. Let O be this value.
  2. Perform ? RequireInternalSlot(O, [[Iterated]]).
  3. Let iterator be O.[[Iterated]].[[Iterator]].
  4. Assert: iterator is an Object.
  5. Let returnMethod be ? GetMethod(iterator, "return").
  6. If returnMethod is undefined, then
    1. Return CreateIteratorResultObject(undefined, true).
  7. Return ? Call(returnMethod, iterator).

27.1.3.2.2 Iterator.prototype

The initial value of Iterator.prototype is the Iterator prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

27.1.4 Properties of the Iterator Prototype Object

The Iterator prototype object:

Note

All objects defined in this specification that implement the iterator interface also inherit from %Iterator.prototype%. ECMAScript code may also define objects that inherit from %Iterator.prototype%. %Iterator.prototype% provides a place where additional methods that are applicable to all iterator objects may be added.

The following expression is one way that ECMAScript code can access the %Iterator.prototype% object:

Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))

27.1.4.1 Iterator.prototype.constructor

Iterator.prototype.constructor is an accessor property with attributes { [[Enumerable]]: false, [[Configurable]]: true }. The [[Get]] and [[Set]] attributes are defined as follows:

27.1.4.1.1 get Iterator.prototype.constructor

The value of the [[Get]] attribute is a built-in function that requires no arguments. It performs the following steps when called:

  1. Return %Iterator%.

27.1.4.1.2 set Iterator.prototype.constructor

The value of the [[Set]] attribute is a built-in function that takes an argument v. It performs the following steps when called:

  1. Perform ? SetterThatIgnoresPrototypeProperties(this value, %Iterator.prototype%, "constructor", v).
  2. Return undefined.
Note

Unlike the "constructor" property on most built-in prototypes, for web-compatibility reasons this property must be an accessor.

27.1.4.2 Iterator.prototype.drop ( limit )

This method performs the following steps when called:

  1. Let O be the this value.
  2. If O is not an Object, throw a TypeError exception.
  3. Let iterated be the Iterator Record { [[Iterator]]: O, [[NextMethod]]: undefined, [[Done]]: false }.
  4. Let numLimit be Completion(ToNumber(limit)).
  5. IfAbruptCloseIterator(numLimit, iterated).
  6. If numLimit is NaN, then
    1. Let error be ThrowCompletion(a newly created RangeError object).
    2. Return ? IteratorClose(iterated, error).
  7. Let integerLimit be ! ToIntegerOrInfinity(numLimit).
  8. If integerLimit < 0, then
    1. Let error be ThrowCompletion(a newly created RangeError object).
    2. Return ? IteratorClose(iterated, error).
  9. Set iterated to ? GetIteratorDirect(O).
  10. Let closure be a new Abstract Closure with no parameters that captures iterated and integerLimit and performs the following steps when called:
    1. Let remaining be integerLimit.
    2. Repeat, while remaining > 0,
      1. If remaining ≠ +∞, then
        1. Set remaining to remaining - 1.
      2. Let next be ? IteratorStep(iterated).
      3. If next is done, return ReturnCompletion(undefined).
    3. Repeat,
      1. Let value be ? IteratorStepValue(iterated).
      2. If value is done, return ReturnCompletion(undefined).
      3. Let completion be Completion(Yield(value)).
      4. IfAbruptCloseIterator(completion, iterated).
  11. Let result be CreateIteratorFromClosure(closure, "Iterator Helper", %IteratorHelperPrototype%, « [[UnderlyingIterator]] »).
  12. Set result.[[UnderlyingIterator]] to iterated.
  13. Return result.

27.1.4.3 Iterator.prototype.every ( predicate )

This method performs the following steps when called:

  1. Let O be the this value.
  2. If O is not an Object, throw a TypeError exception.
  3. Let iterated be the Iterator Record { [[Iterator]]: O, [[NextMethod]]: undefined, [[Done]]: false }.
  4. If IsCallable(predicate) is false, then
    1. Let error be ThrowCompletion(a newly created TypeError object).
    2. Return ? IteratorClose(iterated, error).
  5. Set iterated to ? GetIteratorDirect(O).
  6. Let counter be 0.
  7. Repeat,
    1. Let value be ? IteratorStepValue(iterated).
    2. If value is done, return true.
    3. Let result be Completion(Call(predicate, undefined, « value, 𝔽(counter) »)).
    4. IfAbruptCloseIterator(result, iterated).
    5. If ToBoolean(result) is false, return ? IteratorClose(iterated, NormalCompletion(false)).
    6. Set counter to counter + 1.

27.1.4.4 Iterator.prototype.filter ( predicate )

This method performs the following steps when called:

  1. Let O be the this value.
  2. If O is not an Object, throw a TypeError exception.
  3. Let iterated be the Iterator Record { [[Iterator]]: O, [[NextMethod]]: undefined, [[Done]]: false }.
  4. If IsCallable(predicate) is false, then
    1. Let error be ThrowCompletion(a newly created TypeError object).
    2. Return ? IteratorClose(iterated, error).
  5. Set iterated to ? GetIteratorDirect(O).
  6. Let closure be a new Abstract Closure with no parameters that captures iterated and predicate and performs the following steps when called:
    1. Let counter be 0.
    2. Repeat,
      1. Let value be ? IteratorStepValue(iterated).
      2. If value is done, return ReturnCompletion(undefined).
      3. Let selected be Completion(Call(predicate, undefined, « value, 𝔽(counter) »)).
      4. IfAbruptCloseIterator(selected, iterated).
      5. If ToBoolean(selected) is true, then
        1. Let completion be Completion(Yield(value)).
        2. IfAbruptCloseIterator(completion, iterated).
      6. Set counter to counter + 1.
  7. Let result be CreateIteratorFromClosure(closure, "Iterator Helper", %IteratorHelperPrototype%, « [[UnderlyingIterator]] »).
  8. Set result.[[UnderlyingIterator]] to iterated.
  9. Return result.

27.1.4.5 Iterator.prototype.find ( predicate )

This method performs the following steps when called:

  1. Let O be the this value.
  2. If O is not an Object, throw a TypeError exception.
  3. Let iterated be the Iterator Record { [[Iterator]]: O, [[NextMethod]]: undefined, [[Done]]: false }.
  4. If IsCallable(predicate) is false, then
    1. Let error be ThrowCompletion(a newly created TypeError object).
    2. Return ? IteratorClose(iterated, error).
  5. Set iterated to ? GetIteratorDirect(O).
  6. Let counter be 0.
  7. Repeat,
    1. Let value be ? IteratorStepValue(iterated).
    2. If value is done, return undefined.
    3. Let result be Completion(Call(predicate, undefined, « value, 𝔽(counter) »)).
    4. IfAbruptCloseIterator(result, iterated).
    5. If ToBoolean(result) is true, return ? IteratorClose(iterated, NormalCompletion(value)).
    6. Set counter to counter + 1.

27.1.4.6 Iterator.prototype.flatMap ( mapper )

This method performs the following steps when called:

  1. Let O be the this value.
  2. If O is not an Object, throw a TypeError exception.
  3. Let iterated be the Iterator Record { [[Iterator]]: O, [[NextMethod]]: undefined, [[Done]]: false }.
  4. If IsCallable(mapper) is false, then
    1. Let error be ThrowCompletion(a newly created TypeError object).
    2. Return ? IteratorClose(iterated, error).
  5. Set iterated to ? GetIteratorDirect(O).
  6. Let closure be a new Abstract Closure with no parameters that captures iterated and mapper and performs the following steps when called:
    1. Let counter be 0.
    2. Repeat,
      1. Let value be ? IteratorStepValue(iterated).
      2. If value is done, return ReturnCompletion(undefined).
      3. Let mapped be Completion(Call(mapper, undefined, « value, 𝔽(counter) »)).
      4. IfAbruptCloseIterator(mapped, iterated).
      5. Let innerIterator be Completion(GetIteratorFlattenable(mapped, reject-primitives)).
      6. IfAbruptCloseIterator(innerIterator, iterated).
      7. Let innerAlive be true.
      8. Repeat, while innerAlive is true,
        1. Let innerValue be Completion(IteratorStepValue(innerIterator)).
        2. IfAbruptCloseIterator(innerValue, iterated).
        3. If innerValue is done, then
          1. Set innerAlive to false.
        4. Else,
          1. Let completion be Completion(Yield(innerValue)).
          2. If completion is an abrupt completion, then
            1. Let backupCompletion be Completion(IteratorClose(innerIterator, completion)).
            2. IfAbruptCloseIterator(backupCompletion, iterated).
            3. Return ? IteratorClose(iterated, completion).
      9. Set counter to counter + 1.
  7. Let result be CreateIteratorFromClosure(closure, "Iterator Helper", %IteratorHelperPrototype%, « [[UnderlyingIterator]] »).
  8. Set result.[[UnderlyingIterator]] to iterated.
  9. Return result.

27.1.4.7 Iterator.prototype.forEach ( procedure )

This method performs the following steps when called:

  1. Let O be the this value.
  2. If O is not an Object, throw a TypeError exception.
  3. Let iterated be the Iterator Record { [[Iterator]]: O, [[NextMethod]]: undefined, [[Done]]: false }.
  4. If IsCallable(procedure) is false, then
    1. Let error be ThrowCompletion(a newly created TypeError object).
    2. Return ? IteratorClose(iterated, error).
  5. Set iterated to ? GetIteratorDirect(O).
  6. Let counter be 0.
  7. Repeat,
    1. Let value be ? IteratorStepValue(iterated).
    2. If value is done, return undefined.
    3. Let result be Completion(Call(procedure, undefined, « value, 𝔽(counter) »)).
    4. IfAbruptCloseIterator(result, iterated).
    5. Set counter to counter + 1.

27.1.4.8 Iterator.prototype.map ( mapper )

This method performs the following steps when called:

  1. Let O be the this value.
  2. If O is not an Object, throw a TypeError exception.
  3. Let iterated be the Iterator Record { [[Iterator]]: O, [[NextMethod]]: undefined, [[Done]]: false }.
  4. If IsCallable(mapper) is false, then
    1. Let error be ThrowCompletion(a newly created TypeError object).
    2. Return ? IteratorClose(iterated, error).
  5. Set iterated to ? GetIteratorDirect(O).
  6. Let closure be a new Abstract Closure with no parameters that captures iterated and mapper and performs the following steps when called:
    1. Let counter be 0.
    2. Repeat,
      1. Let value be ? IteratorStepValue(iterated).
      2. If value is done, return ReturnCompletion(undefined).
      3. Let mapped be Completion(Call(mapper, undefined, « value, 𝔽(counter) »)).
      4. IfAbruptCloseIterator(mapped, iterated).
      5. Let completion be Completion(Yield(mapped)).
      6. IfAbruptCloseIterator(completion, iterated).
      7. Set counter to counter + 1.
  7. Let result be CreateIteratorFromClosure(closure, "Iterator Helper", %IteratorHelperPrototype%, « [[UnderlyingIterator]] »).
  8. Set result.[[UnderlyingIterator]] to iterated.
  9. Return result.

27.1.4.9 Iterator.prototype.reduce ( reducer [ , initialValue ] )

This method performs the following steps when called:

  1. Let O be the this value.
  2. If O is not an Object, throw a TypeError exception.
  3. Let iterated be the Iterator Record { [[Iterator]]: O, [[NextMethod]]: undefined, [[Done]]: false }.
  4. If IsCallable(reducer) is false, then
    1. Let error be ThrowCompletion(a newly created TypeError object).
    2. Return ? IteratorClose(iterated, error).
  5. Set iterated to ? GetIteratorDirect(O).
  6. If initialValue is not present, then
    1. Let accumulator be ? IteratorStepValue(iterated).
    2. If accumulator is done, throw a TypeError exception.
    3. Let counter be 1.
  7. Else,
    1. Let accumulator be initialValue.
    2. Let counter be 0.
  8. Repeat,
    1. Let value be ? IteratorStepValue(iterated).
    2. If value is done, return accumulator.
    3. Let result be Completion(Call(reducer, undefined, « accumulator, value, 𝔽(counter) »)).
    4. IfAbruptCloseIterator(result, iterated).
    5. Set accumulator to result.
    6. Set counter to counter + 1.

27.1.4.10 Iterator.prototype.some ( predicate )

This method performs the following steps when called:

  1. Let O be the this value.
  2. If O is not an Object, throw a TypeError exception.
  3. Let iterated be the Iterator Record { [[Iterator]]: O, [[NextMethod]]: undefined, [[Done]]: false }.
  4. If IsCallable(predicate) is false, then
    1. Let error be ThrowCompletion(a newly created TypeError object).
    2. Return ? IteratorClose(iterated, error).
  5. Set iterated to ? GetIteratorDirect(O).
  6. Let counter be 0.
  7. Repeat,
    1. Let value be ? IteratorStepValue(iterated).
    2. If value is done, return false.
    3. Let result be Completion(Call(predicate, undefined, « value, 𝔽(counter) »)).
    4. IfAbruptCloseIterator(result, iterated).
    5. If ToBoolean(result) is true, return ? IteratorClose(iterated, NormalCompletion(true)).
    6. Set counter to counter + 1.

27.1.4.11 Iterator.prototype.take ( limit )

This method performs the following steps when called:

  1. Let O be the this value.
  2. If O is not an Object, throw a TypeError exception.
  3. Let iterated be the Iterator Record { [[Iterator]]: O, [[NextMethod]]: undefined, [[Done]]: false }.
  4. Let numLimit be Completion(ToNumber(limit)).
  5. IfAbruptCloseIterator(numLimit, iterated).
  6. If numLimit is NaN, then
    1. Let error be ThrowCompletion(a newly created RangeError object).
    2. Return ? IteratorClose(iterated, error).
  7. Let integerLimit be ! ToIntegerOrInfinity(numLimit).
  8. If integerLimit < 0, then
    1. Let error be ThrowCompletion(a newly created RangeError object).
    2. Return ? IteratorClose(iterated, error).
  9. Set iterated to ? GetIteratorDirect(O).
  10. Let closure be a new Abstract Closure with no parameters that captures iterated and integerLimit and performs the following steps when called:
    1. Let remaining be integerLimit.
    2. Repeat,
      1. If remaining = 0, then
        1. Return ? IteratorClose(iterated, ReturnCompletion(undefined)).
      2. If remaining ≠ +∞, then
        1. Set remaining to remaining - 1.
      3. Let value be ? IteratorStepValue(iterated).
      4. If value is done, return ReturnCompletion(undefined).
      5. Let completion be Completion(Yield(value)).
      6. IfAbruptCloseIterator(completion, iterated).
  11. Let result be CreateIteratorFromClosure(closure, "Iterator Helper", %IteratorHelperPrototype%, « [[UnderlyingIterator]] »).
  12. Set result.[[UnderlyingIterator]] to iterated.
  13. Return result.

27.1.4.12 Iterator.prototype.toArray ( )

This method performs the following steps when called:

  1. Let O be the this value.
  2. If O is not an Object, throw a TypeError exception.
  3. Let iterated be ? GetIteratorDirect(O).
  4. Let items be a new empty List.
  5. Repeat,
    1. Let value be ? IteratorStepValue(iterated).
    2. If value is done, return CreateArrayFromList(items).
    3. Append value to items.

27.1.4.13 Iterator.prototype [ %Symbol.iterator% ] ( )

This function performs the following steps when called:

  1. Return the this value.

The value of the "name" property of this function is "[Symbol.iterator]".

27.1.4.14 Iterator.prototype [ %Symbol.toStringTag% ]

Iterator.prototype[%Symbol.toStringTag%] is an accessor property with attributes { [[Enumerable]]: false, [[Configurable]]: true }. The [[Get]] and [[Set]] attributes are defined as follows:

27.1.4.14.1 get Iterator.prototype [ %Symbol.toStringTag% ]

The value of the [[Get]] attribute is a built-in function that requires no arguments. It performs the following steps when called:

  1. Return "Iterator".

27.1.4.14.2 set Iterator.prototype [ %Symbol.toStringTag% ]

The value of the [[Set]] attribute is a built-in function that takes an argument v. It performs the following steps when called:

  1. Perform ? SetterThatIgnoresPrototypeProperties(this value, %Iterator.prototype%, %Symbol.toStringTag%, v).
  2. Return undefined.
Note

Unlike the %Symbol.toStringTag% property on most built-in prototypes, for web-compatibility reasons this property must be an accessor.

27.1.5 The %AsyncIteratorPrototype% Object

The %AsyncIteratorPrototype% object:

Note

All objects defined in this specification that implement the async iterator interface also inherit from %AsyncIteratorPrototype%. ECMAScript code may also define objects that inherit from %AsyncIteratorPrototype%. The %AsyncIteratorPrototype% object provides a place where additional methods that are applicable to all async iterator objects may be added.

27.1.5.1 %AsyncIteratorPrototype% [ %Symbol.asyncIterator% ] ( )

This function performs the following steps when called:

  1. Return the this value.

The value of the "name" property of this function is "[Symbol.asyncIterator]".

27.1.6 Async-from-Sync Iterator Objects

An Async-from-Sync Iterator object is an async iterator that adapts a specific synchronous iterator. Async-from-Sync Iterator objects are never directly accessible to ECMAScript code. There is not a named constructor for Async-from-Sync Iterator objects. Instead, Async-from-Sync Iterator objects are created by the CreateAsyncFromSyncIterator abstract operation as needed.

27.1.6.1 CreateAsyncFromSyncIterator ( syncIteratorRecord )

The abstract operation CreateAsyncFromSyncIterator takes argument syncIteratorRecord (an Iterator Record) and returns an Iterator Record. It is used to create an async Iterator Record from a synchronous Iterator Record. It performs the following steps when called:

  1. Let asyncIterator be OrdinaryObjectCreate(%AsyncFromSyncIteratorPrototype%, « [[SyncIteratorRecord]] »).
  2. Set asyncIterator.[[SyncIteratorRecord]] to syncIteratorRecord.
  3. Let nextMethod be ! Get(asyncIterator, "next").
  4. Let iteratorRecord be the Iterator Record { [[Iterator]]: asyncIterator, [[NextMethod]]: nextMethod, [[Done]]: false }.
  5. Return iteratorRecord.

27.1.6.2 The %AsyncFromSyncIteratorPrototype% Object

The %AsyncFromSyncIteratorPrototype% object:

27.1.6.2.1 %AsyncFromSyncIteratorPrototype%.next ( [ value ] )

  1. Let O be the this value.
  2. Assert: O is an Object that has a [[SyncIteratorRecord]] internal slot.
  3. Let promiseCapability be ! NewPromiseCapability(%Promise%).
  4. Let syncIteratorRecord be O.[[SyncIteratorRecord]].
  5. If value is present, then
    1. Let result be Completion(IteratorNext(syncIteratorRecord, value)).
  6. Else,
    1. Let result be Completion(IteratorNext(syncIteratorRecord)).
  7. IfAbruptRejectPromise(result, promiseCapability).
  8. Return AsyncFromSyncIteratorContinuation(result, promiseCapability, syncIteratorRecord, true).

27.1.6.2.2 %AsyncFromSyncIteratorPrototype%.return ( [ value ] )

  1. Let O be the this value.
  2. Assert: O is an Object that has a [[SyncIteratorRecord]] internal slot.
  3. Let promiseCapability be ! NewPromiseCapability(%Promise%).
  4. Let syncIteratorRecord be O.[[SyncIteratorRecord]].
  5. Let syncIterator be syncIteratorRecord.[[Iterator]].
  6. Let return be Completion(GetMethod(syncIterator, "return")).
  7. IfAbruptRejectPromise(return, promiseCapability).
  8. If return is undefined, then
    1. Let iteratorResult be CreateIteratorResultObject(value, true).
    2. Perform ! Call(promiseCapability.[[Resolve]], undefined, « iteratorResult »).
    3. Return promiseCapability.[[Promise]].
  9. If value is present, then
    1. Let result be Completion(Call(return, syncIterator, « value »)).
  10. Else,
    1. Let result be Completion(Call(return, syncIterator)).
  11. IfAbruptRejectPromise(result, promiseCapability).
  12. If result is not an Object, then
    1. Perform ! Call(promiseCapability.[[Reject]], undefined, « a newly created TypeError object »).
    2. Return promiseCapability.[[Promise]].
  13. Return AsyncFromSyncIteratorContinuation(result, promiseCapability, syncIteratorRecord, false).

27.1.6.2.3 %AsyncFromSyncIteratorPrototype%.throw ( [ value ] )

Note
In this specification, value is always provided, but is left optional for consistency with %AsyncFromSyncIteratorPrototype%.return ( [ value ] ).
  1. Let O be the this value.
  2. Assert: O is an Object that has a [[SyncIteratorRecord]] internal slot.
  3. Let promiseCapability be ! NewPromiseCapability(%Promise%).
  4. Let syncIteratorRecord be O.[[SyncIteratorRecord]].
  5. Let syncIterator be syncIteratorRecord.[[Iterator]].
  6. Let throw be Completion(GetMethod(syncIterator, "throw")).
  7. IfAbruptRejectPromise(throw, promiseCapability).
  8. If throw is undefined, then
    1. NOTE: If syncIterator does not have a throw method, close it to give it a chance to clean up before we reject the capability.
    2. Let closeCompletion be NormalCompletion(empty).
    3. Let result be Completion(IteratorClose(syncIteratorRecord, closeCompletion)).
    4. IfAbruptRejectPromise(result, promiseCapability).
    5. NOTE: The next step throws a TypeError to indicate that there was a protocol violation: syncIterator does not have a throw method.
    6. NOTE: If closing syncIterator does not throw then the result of that operation is ignored, even if it yields a rejected promise.
    7. Perform ! Call(promiseCapability.[[Reject]], undefined, « a newly created TypeError object »).
    8. Return promiseCapability.[[Promise]].
  9. If value is present, then
    1. Let result be Completion(Call(throw, syncIterator, « value »)).
  10. Else,
    1. Let result be Completion(Call(throw, syncIterator)).
  11. IfAbruptRejectPromise(result, promiseCapability).
  12. If result is not an Object, then
    1. Perform ! Call(promiseCapability.[[Reject]], undefined, « a newly created TypeError object »).
    2. Return promiseCapability.[[Promise]].
  13. Return AsyncFromSyncIteratorContinuation(result, promiseCapability, syncIteratorRecord, true).

27.1.6.3 Properties of Async-from-Sync Iterator Instances

Async-from-Sync Iterator instances are ordinary objects that inherit properties from the %AsyncFromSyncIteratorPrototype% intrinsic object. Async-from-Sync Iterator instances are initially created with the internal slots listed in Table 89.

Table 89: Internal Slots of Async-from-Sync Iterator Instances
Internal Slot Type Description
[[SyncIteratorRecord]] an Iterator Record Represents the original synchronous iterator which is being adapted.

27.1.6.4 AsyncFromSyncIteratorContinuation ( result, promiseCapability, syncIteratorRecord, closeOnRejection )

The abstract operation AsyncFromSyncIteratorContinuation takes arguments result (an Object), promiseCapability (a PromiseCapability Record for an intrinsic %Promise%), syncIteratorRecord (an Iterator Record), and closeOnRejection (a Boolean) and returns a Promise. It performs the following steps when called:

  1. NOTE: Because promiseCapability is derived from the intrinsic %Promise%, the calls to promiseCapability.[[Reject]] entailed by the use IfAbruptRejectPromise below are guaranteed not to throw.
  2. Let done be Completion(IteratorComplete(result)).
  3. IfAbruptRejectPromise(done, promiseCapability).
  4. Let value be Completion(IteratorValue(result)).
  5. IfAbruptRejectPromise(value, promiseCapability).
  6. Let valueWrapper be Completion(PromiseResolve(%Promise%, value)).
  7. If valueWrapper is an abrupt completion, done is false, and closeOnRejection is true, then
    1. Set valueWrapper to Completion(IteratorClose(syncIteratorRecord, valueWrapper)).
  8. IfAbruptRejectPromise(valueWrapper, promiseCapability).
  9. Let unwrap be a new Abstract Closure with parameters (v) that captures done and performs the following steps when called:
    1. Return CreateIteratorResultObject(v, done).
  10. Let onFulfilled be CreateBuiltinFunction(unwrap, 1, "", « »).
  11. NOTE: onFulfilled is used when processing the "value" property of an IteratorResult object in order to wait for its value if it is a promise and re-package the result in a new "unwrapped" IteratorResult object.
  12. If done is true, or if closeOnRejection is false, then
    1. Let onRejected be undefined.
  13. Else,
    1. Let closeIterator be a new Abstract Closure with parameters (error) that captures syncIteratorRecord and performs the following steps when called:
      1. Return ? IteratorClose(syncIteratorRecord, ThrowCompletion(error)).
    2. Let onRejected be CreateBuiltinFunction(closeIterator, 1, "", « »).
    3. NOTE: onRejected is used to close the Iterator when the "value" property of an IteratorResult object it yields is a rejected promise.
  14. Perform PerformPromiseThen(valueWrapper, onFulfilled, onRejected, promiseCapability).
  15. Return promiseCapability.[[Promise]].

27.2 Promise Objects

A Promise is an object that is used as a placeholder for the eventual results of a deferred (and possibly asynchronous) computation.

Any Promise is in one of three mutually exclusive states: fulfilled, rejected, and pending:

  • A promise p is fulfilled if p.then(f, r) will immediately enqueue a Job to call the function f.
  • A promise p is rejected if p.then(f, r) will immediately enqueue a Job to call the function r.
  • A promise is pending if it is neither fulfilled nor rejected.

A promise is said to be settled if it is not pending, i.e. if it is either fulfilled or rejected.

A promise is resolved if it is settled or if it has been “locked in” to match the state of another promise. Attempting to resolve or reject a resolved promise has no effect. A promise is unresolved if it is not resolved. An unresolved promise is always in the pending state. A resolved promise may be pending, fulfilled or rejected.

27.2.1 Promise Abstract Operations

27.2.1.1 PromiseCapability Records

A PromiseCapability Record is a Record value used to encapsulate a Promise or promise-like object along with the functions that are capable of resolving or rejecting that promise. PromiseCapability Records are produced by the NewPromiseCapability abstract operation.

PromiseCapability Records have the fields listed in Table 90.

Table 90: PromiseCapability Record Fields
Field Name Value Meaning
[[Promise]] an Object An object that is usable as a promise.
[[Resolve]] a function object The function that is used to resolve the given promise.
[[Reject]] a function object The function that is used to reject the given promise.

27.2.1.1.1 IfAbruptRejectPromise ( value, capability )

IfAbruptRejectPromise is a shorthand for a sequence of algorithm steps that use a PromiseCapability Record. An algorithm step of the form:

  1. IfAbruptRejectPromise(value, capability).

means the same thing as:

  1. Assert: value is a Completion Record.
  2. If value is an abrupt completion, then
    1. Perform ? Call(capability.[[Reject]], undefined, « value.[[Value]] »).
    2. Return capability.[[Promise]].
  3. Else,
    1. Set value to ! value.

27.2.1.2 PromiseReaction Records

A PromiseReaction Record is a Record value used to store information about how a promise should react when it becomes resolved or rejected with a given value. PromiseReaction Records are created by the PerformPromiseThen abstract operation, and are used by the Abstract Closure returned by NewPromiseReactionJob.

PromiseReaction Records have the fields listed in Table 91.

Table 91: PromiseReaction Record Fields
Field Name Value Meaning
[[Capability]] a PromiseCapability Record or undefined The capabilities of the promise for which this record provides a reaction handler.
[[Type]] fulfill or reject The [[Type]] is used when [[Handler]] is empty to allow for behaviour specific to the settlement type.
[[Handler]] a JobCallback Record or empty The function that should be applied to the incoming value, and whose return value will govern what happens to the derived promise. If [[Handler]] is empty, a function that depends on the value of [[Type]] will be used instead.

27.2.1.3 CreateResolvingFunctions ( promise )

The abstract operation CreateResolvingFunctions takes argument promise (a Promise) and returns a Record with fields [[Resolve]] (a function object) and [[Reject]] (a function object). It performs the following steps when called:

  1. Let alreadyResolved be the Record { [[Value]]: false }.
  2. Let stepsResolve be the algorithm steps defined in Promise Resolve Functions.
  3. Let lengthResolve be the number of non-optional parameters of the function definition in Promise Resolve Functions.
  4. Let resolve be CreateBuiltinFunction(stepsResolve, lengthResolve, "", « [[Promise]], [[AlreadyResolved]] »).
  5. Set resolve.[[Promise]] to promise.
  6. Set resolve.[[AlreadyResolved]] to alreadyResolved.
  7. Let stepsReject be the algorithm steps defined in Promise Reject Functions.
  8. Let lengthReject be the number of non-optional parameters of the function definition in Promise Reject Functions.
  9. Let reject be CreateBuiltinFunction(stepsReject, lengthReject, "", « [[Promise]], [[AlreadyResolved]] »).
  10. Set reject.[[Promise]] to promise.
  11. Set reject.[[AlreadyResolved]] to alreadyResolved.
  12. Return the Record { [[Resolve]]: resolve, [[Reject]]: reject }.

27.2.1.3.1 Promise Reject Functions

A promise reject function is an anonymous built-in function that has [[Promise]] and [[AlreadyResolved]] internal slots.

When a promise reject function is called with argument reason, the following steps are taken:

  1. Let F be the active function object.
  2. Assert: F has a [[Promise]] internal slot whose value is an Object.
  3. Let promise be F.[[Promise]].
  4. Let alreadyResolved be F.[[AlreadyResolved]].
  5. If alreadyResolved.[[Value]] is true, return undefined.
  6. Set alreadyResolved.[[Value]] to true.
  7. Perform RejectPromise(promise, reason).
  8. Return undefined.

The "length" property of a promise reject function is 1𝔽.

27.2.1.3.2 Promise Resolve Functions

A promise resolve function is an anonymous built-in function that has [[Promise]] and [[AlreadyResolved]] internal slots.

When a promise resolve function is called with argument resolution, the following steps are taken:

  1. Let F be the active function object.
  2. Assert: F has a [[Promise]] internal slot whose value is an Object.
  3. Let promise be F.[[Promise]].
  4. Let alreadyResolved be F.[[AlreadyResolved]].
  5. If alreadyResolved.[[Value]] is true, return undefined.
  6. Set alreadyResolved.[[Value]] to true.
  7. If SameValue(resolution, promise) is true, then
    1. Let selfResolutionError be a newly created TypeError object.
    2. Perform RejectPromise(promise, selfResolutionError).
    3. Return undefined.
  8. If resolution is not an Object, then
    1. Perform FulfillPromise(promise, resolution).
    2. Return undefined.
  9. Let then be Completion(Get(resolution, "then")).
  10. If then is an abrupt completion, then
    1. Perform RejectPromise(promise, then.[[Value]]).
    2. Return undefined.
  11. Let thenAction be then.[[Value]].
  12. If IsCallable(thenAction) is false, then
    1. Perform FulfillPromise(promise, resolution).
    2. Return undefined.
  13. Let thenJobCallback be HostMakeJobCallback(thenAction).
  14. Let job be NewPromiseResolveThenableJob(promise, resolution, thenJobCallback).
  15. Perform HostEnqueuePromiseJob(job.[[Job]], job.[[Realm]]).
  16. Return undefined.

The "length" property of a promise resolve function is 1𝔽.

27.2.1.4 FulfillPromise ( promise, value )

The abstract operation FulfillPromise takes arguments promise (a Promise) and value (an ECMAScript language value) and returns unused. It performs the following steps when called:

  1. Assert: promise.[[PromiseState]] is pending.
  2. Let reactions be promise.[[PromiseFulfillReactions]].
  3. Set promise.[[PromiseResult]] to value.
  4. Set promise.[[PromiseFulfillReactions]] to undefined.
  5. Set promise.[[PromiseRejectReactions]] to undefined.
  6. Set promise.[[PromiseState]] to fulfilled.
  7. Perform TriggerPromiseReactions(reactions, value).
  8. Return unused.

27.2.1.5 NewPromiseCapability ( C )

The abstract operation NewPromiseCapability takes argument C (an ECMAScript language value) and returns either a normal completion containing a PromiseCapability Record or a throw completion. It attempts to use C as a constructor in the fashion of the built-in Promise constructor to create a promise and extract its resolve and reject functions. The promise plus the resolve and reject functions are used to initialize a new PromiseCapability Record. It performs the following steps when called:

  1. If IsConstructor(C) is false, throw a TypeError exception.
  2. NOTE: C is assumed to be a constructor function that supports the parameter conventions of the Promise constructor (see 27.2.3.1).
  3. Let resolvingFunctions be the Record { [[Resolve]]: undefined, [[Reject]]: undefined }.
  4. Let executorClosure be a new Abstract Closure with parameters (resolve, reject) that captures resolvingFunctions and performs the following steps when called:
    1. If resolvingFunctions.[[Resolve]] is not undefined, throw a TypeError exception.
    2. If resolvingFunctions.[[Reject]] is not undefined, throw a TypeError exception.
    3. Set resolvingFunctions.[[Resolve]] to resolve.
    4. Set resolvingFunctions.[[Reject]] to reject.
    5. Return NormalCompletion(undefined).
  5. Let executor be CreateBuiltinFunction(executorClosure, 2, "", « »).
  6. Let promise be ? Construct(C, « executor »).
  7. If IsCallable(resolvingFunctions.[[Resolve]]) is false, throw a TypeError exception.
  8. If IsCallable(resolvingFunctions.[[Reject]]) is false, throw a TypeError exception.
  9. Return the PromiseCapability Record { [[Promise]]: promise, [[Resolve]]: resolvingFunctions.[[Resolve]], [[Reject]]: resolvingFunctions.[[Reject]] }.
Note

This abstract operation supports Promise subclassing, as it is generic on any constructor that calls a passed executor function argument in the same way as the Promise constructor. It is used to generalize static methods of the Promise constructor to any subclass.

27.2.1.6 IsPromise ( x )

The abstract operation IsPromise takes argument x (an ECMAScript language value) and returns a Boolean. It checks for the promise brand on an object. It performs the following steps when called:

  1. If x is not an Object, return false.
  2. If x does not have a [[PromiseState]] internal slot, return false.
  3. Return true.

27.2.1.7 RejectPromise ( promise, reason )

The abstract operation RejectPromise takes arguments promise (a Promise) and reason (an ECMAScript language value) and returns unused. It performs the following steps when called:

  1. Assert: promise.[[PromiseState]] is pending.
  2. Let reactions be promise.[[PromiseRejectReactions]].
  3. Set promise.[[PromiseResult]] to reason.
  4. Set promise.[[PromiseFulfillReactions]] to undefined.
  5. Set promise.[[PromiseRejectReactions]] to undefined.
  6. Set promise.[[PromiseState]] to rejected.
  7. If promise.[[PromiseIsHandled]] is false, perform HostPromiseRejectionTracker(promise, "reject").
  8. Perform TriggerPromiseReactions(reactions, reason).
  9. Return unused.

27.2.1.8 TriggerPromiseReactions ( reactions, argument )

The abstract operation TriggerPromiseReactions takes arguments reactions (a List of PromiseReaction Records) and argument (an ECMAScript language value) and returns unused. It enqueues a new Job for each record in reactions. Each such Job processes the [[Type]] and [[Handler]] of the PromiseReaction Record, and if the [[Handler]] is not empty, calls it passing the given argument. If the [[Handler]] is empty, the behaviour is determined by the [[Type]]. It performs the following steps when called:

  1. For each element reaction of reactions, do
    1. Let job be NewPromiseReactionJob(reaction, argument).
    2. Perform HostEnqueuePromiseJob(job.[[Job]], job.[[Realm]]).
  2. Return unused.

27.2.1.9 HostPromiseRejectionTracker ( promise, operation )

The host-defined abstract operation HostPromiseRejectionTracker takes arguments promise (a Promise) and operation ("reject" or "handle") and returns unused. It allows host environments to track promise rejections.

The default implementation of HostPromiseRejectionTracker is to return unused.

Note 1

HostPromiseRejectionTracker is called in two scenarios:

  • When a promise is rejected without any handlers, it is called with its operation argument set to "reject".
  • When a handler is added to a rejected promise for the first time, it is called with its operation argument set to "handle".

A typical implementation of HostPromiseRejectionTracker might try to notify developers of unhandled rejections, while also being careful to notify them if such previous notifications are later invalidated by new handlers being attached.

Note 2

If operation is "handle", an implementation should not hold a reference to promise in a way that would interfere with garbage collection. An implementation may hold a reference to promise if operation is "reject", since it is expected that rejections will be rare and not on hot code paths.

27.2.2 Promise Jobs

27.2.2.1 NewPromiseReactionJob ( reaction, argument )

The abstract operation NewPromiseReactionJob takes arguments reaction (a PromiseReaction Record) and argument (an ECMAScript language value) and returns a Record with fields [[Job]] (a Job Abstract Closure) and [[Realm]] (a Realm Record or null). It returns a new Job Abstract Closure that applies the appropriate handler to the incoming value, and uses the handler's return value to resolve or reject the derived promise associated with that handler. It performs the following steps when called:

  1. Let job be a new Job Abstract Closure with no parameters that captures reaction and argument and performs the following steps when called:
    1. Let promiseCapability be reaction.[[Capability]].
    2. Let type be reaction.[[Type]].
    3. Let handler be reaction.[[Handler]].
    4. If handler is empty, then
      1. If type is fulfill, then
        1. Let handlerResult be NormalCompletion(argument).
      2. Else,
        1. Assert: type is reject.
        2. Let handlerResult be ThrowCompletion(argument).
    5. Else,
      1. Let handlerResult be Completion(HostCallJobCallback(handler, undefined, « argument »)).
    6. If promiseCapability is undefined, then
      1. Assert: handlerResult is not an abrupt completion.
      2. Return empty.
    7. Assert: promiseCapability is a PromiseCapability Record.
    8. If handlerResult is an abrupt completion, then
      1. Return ? Call(promiseCapability.[[Reject]], undefined, « handlerResult.[[Value]] »).
    9. Else,
      1. Return ? Call(promiseCapability.[[Resolve]], undefined, « handlerResult.[[Value]] »).
  2. Let handlerRealm be null.
  3. If reaction.[[Handler]] is not empty, then
    1. Let getHandlerRealmResult be Completion(GetFunctionRealm(reaction.[[Handler]].[[Callback]])).
    2. If getHandlerRealmResult is a normal completion, set handlerRealm to getHandlerRealmResult.[[Value]].
    3. Else, set handlerRealm to the current Realm Record.
    4. NOTE: handlerRealm is never null unless the handler is undefined. When the handler is a revoked Proxy and no ECMAScript code runs, handlerRealm is used to create error objects.
  4. Return the Record { [[Job]]: job, [[Realm]]: handlerRealm }.

27.2.2.2 NewPromiseResolveThenableJob ( promiseToResolve, thenable, then )

The abstract operation NewPromiseResolveThenableJob takes arguments promiseToResolve (a Promise), thenable (an Object), and then (a JobCallback Record) and returns a Record with fields [[Job]] (a Job Abstract Closure) and [[Realm]] (a Realm Record). It performs the following steps when called:

  1. Let job be a new Job Abstract Closure with no parameters that captures promiseToResolve, thenable, and then and performs the following steps when called:
    1. Let resolvingFunctions be CreateResolvingFunctions(promiseToResolve).
    2. Let thenCallResult be Completion(HostCallJobCallback(then, thenable, « resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]] »)).
    3. If thenCallResult is an abrupt completion, then
      1. Return ? Call(resolvingFunctions.[[Reject]], undefined, « thenCallResult.[[Value]] »).
    4. Return ! thenCallResult.
  2. Let getThenRealmResult be Completion(GetFunctionRealm(then.[[Callback]])).
  3. If getThenRealmResult is a normal completion, let thenRealm be getThenRealmResult.[[Value]].
  4. Else, let thenRealm be the current Realm Record.
  5. NOTE: thenRealm is never null. When then.[[Callback]] is a revoked Proxy and no code runs, thenRealm is used to create error objects.
  6. Return the Record { [[Job]]: job, [[Realm]]: thenRealm }.
Note

This Job uses the supplied thenable and its then method to resolve the given promise. This process must take place as a Job to ensure that the evaluation of the then method occurs after evaluation of any surrounding code has completed.

27.2.3 The Promise Constructor

The Promise constructor:

  • is %Promise%.
  • is the initial value of the "Promise" property of the global object.
  • creates and initializes a new Promise when called as a constructor.
  • is not intended to be called as a function and will throw an exception when called in that manner.
  • may be used as the value in an extends clause of a class definition. Subclass constructors that intend to inherit the specified Promise behaviour must include a super call to the Promise constructor to create and initialize the subclass instance with the internal state necessary to support the Promise and Promise.prototype built-in methods.

27.2.3.1 Promise ( executor )

This function performs the following steps when called:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. If IsCallable(executor) is false, throw a TypeError exception.
  3. Let promise be ? OrdinaryCreateFromConstructor(NewTarget, "%Promise.prototype%", « [[PromiseState]], [[PromiseResult]], [[PromiseFulfillReactions]], [[PromiseRejectReactions]], [[PromiseIsHandled]] »).
  4. Set promise.[[PromiseState]] to pending.
  5. Set promise.[[PromiseResult]] to empty.
  6. Set promise.[[PromiseFulfillReactions]] to a new empty List.
  7. Set promise.[[PromiseRejectReactions]] to a new empty List.
  8. Set promise.[[PromiseIsHandled]] to false.
  9. Let resolvingFunctions be CreateResolvingFunctions(promise).
  10. Let completion be Completion(Call(executor, undefined, « resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]] »)).
  11. If completion is an abrupt completion, then
    1. Perform ? Call(resolvingFunctions.[[Reject]], undefined, « completion.[[Value]] »).
  12. Return promise.
Note

The executor argument must be a function object. It is called for initiating and reporting completion of the possibly deferred action represented by this Promise. The executor is called with two arguments: resolve and reject. These are functions that may be used by the executor function to report eventual completion or failure of the deferred computation. Returning from the executor function does not mean that the deferred action has been completed but only that the request to eventually perform the deferred action has been accepted.

The resolve function that is passed to an executor function accepts a single argument. The executor code may eventually call the resolve function to indicate that it wishes to resolve the associated Promise. The argument passed to the resolve function represents the eventual value of the deferred action and can be either the actual fulfillment value or another promise which will provide the value if it is fulfilled.

The reject function that is passed to an executor function accepts a single argument. The executor code may eventually call the reject function to indicate that the associated Promise is rejected and will never be fulfilled. The argument passed to the reject function is used as the rejection value of the promise. Typically it will be an Error object.

The resolve and reject functions passed to an executor function by the Promise constructor have the capability to actually resolve and reject the associated promise. Subclasses may have different constructor behaviour that passes in customized values for resolve and reject.

27.2.4 Properties of the Promise Constructor

The Promise constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • has the following properties:

27.2.4.1 Promise.all ( iterable )

This function returns a new promise which is fulfilled with an array of fulfillment values for the passed promises, or rejects with the reason of the first passed promise that rejects. It resolves all elements of the passed iterable to promises as it runs this algorithm.

  1. Let C be the this value.
  2. Let promiseCapability be ? NewPromiseCapability(C).
  3. Let promiseResolve be Completion(GetPromiseResolve(C)).
  4. IfAbruptRejectPromise(promiseResolve, promiseCapability).
  5. Let iteratorRecord be Completion(GetIterator(iterable, sync)).
  6. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
  7. Let result be Completion(PerformPromiseAll(iteratorRecord, C, promiseCapability, promiseResolve)).
  8. If result is an abrupt completion, then
    1. If iteratorRecord.[[Done]] is false, set result to Completion(IteratorClose(iteratorRecord, result)).
    2. IfAbruptRejectPromise(result, promiseCapability).
  9. Return ! result.
Note

This function requires its this value to be a constructor function that supports the parameter conventions of the Promise constructor.

27.2.4.1.1 GetPromiseResolve ( promiseConstructor )

The abstract operation GetPromiseResolve takes argument promiseConstructor (a constructor) and returns either a normal completion containing a function object or a throw completion. It performs the following steps when called:

  1. Let promiseResolve be ? Get(promiseConstructor, "resolve").
  2. If IsCallable(promiseResolve) is false, throw a TypeError exception.
  3. Return promiseResolve.

27.2.4.1.2 PerformPromiseAll ( iteratorRecord, constructor, resultCapability, promiseResolve )

The abstract operation PerformPromiseAll takes arguments iteratorRecord (an Iterator Record), constructor (a constructor), resultCapability (a PromiseCapability Record), and promiseResolve (a function object) and returns either a normal completion containing an ECMAScript language value or a throw completion. It performs the following steps when called:

  1. Let values be a new empty List.
  2. Let remainingElementsCount be the Record { [[Value]]: 1 }.
  3. Let index be 0.
  4. Repeat,
    1. Let next be ? IteratorStepValue(iteratorRecord).
    2. If next is done, then
      1. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
      2. If remainingElementsCount.[[Value]] = 0, then
        1. Let valuesArray be CreateArrayFromList(values).
        2. Perform ? Call(resultCapability.[[Resolve]], undefined, « valuesArray »).
      3. Return resultCapability.[[Promise]].
    3. Append undefined to values.
    4. Let nextPromise be ? Call(promiseResolve, constructor, « next »).
    5. Let steps be the algorithm steps defined in Promise.all Resolve Element Functions.
    6. Let length be the number of non-optional parameters of the function definition in Promise.all Resolve Element Functions.
    7. Let onFulfilled be CreateBuiltinFunction(steps, length, "", « [[AlreadyCalled]], [[Index]], [[Values]], [[Capability]], [[RemainingElements]] »).
    8. Set onFulfilled.[[AlreadyCalled]] to false.
    9. Set onFulfilled.[[Index]] to index.
    10. Set onFulfilled.[[Values]] to values.
    11. Set onFulfilled.[[Capability]] to resultCapability.
    12. Set onFulfilled.[[RemainingElements]] to remainingElementsCount.
    13. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] + 1.
    14. Perform ? Invoke(nextPromise, "then", « onFulfilled, resultCapability.[[Reject]] »).
    15. Set index to index + 1.

27.2.4.1.3 Promise.all Resolve Element Functions

A Promise.all resolve element function is an anonymous built-in function that is used to resolve a specific Promise.all element. Each Promise.all resolve element function has [[Index]], [[Values]], [[Capability]], [[RemainingElements]], and [[AlreadyCalled]] internal slots.

When a Promise.all resolve element function is called with argument x, the following steps are taken:

  1. Let F be the active function object.
  2. If F.[[AlreadyCalled]] is true, return undefined.
  3. Set F.[[AlreadyCalled]] to true.
  4. Let index be F.[[Index]].
  5. Let values be F.[[Values]].
  6. Let promiseCapability be F.[[Capability]].
  7. Let remainingElementsCount be F.[[RemainingElements]].
  8. Set values[index] to x.
  9. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
  10. If remainingElementsCount.[[Value]] = 0, then
    1. Let valuesArray be CreateArrayFromList(values).
    2. Return ? Call(promiseCapability.[[Resolve]], undefined, « valuesArray »).
  11. Return undefined.

The "length" property of a Promise.all resolve element function is 1𝔽.

27.2.4.2 Promise.allSettled ( iterable )

This function returns a promise that is fulfilled with an array of promise state snapshots, but only after all the original promises have settled, i.e. become either fulfilled or rejected. It resolves all elements of the passed iterable to promises as it runs this algorithm.

  1. Let C be the this value.
  2. Let promiseCapability be ? NewPromiseCapability(C).
  3. Let promiseResolve be Completion(GetPromiseResolve(C)).
  4. IfAbruptRejectPromise(promiseResolve, promiseCapability).
  5. Let iteratorRecord be Completion(GetIterator(iterable, sync)).
  6. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
  7. Let result be Completion(PerformPromiseAllSettled(iteratorRecord, C, promiseCapability, promiseResolve)).
  8. If result is an abrupt completion, then
    1. If iteratorRecord.[[Done]] is false, set result to Completion(IteratorClose(iteratorRecord, result)).
    2. IfAbruptRejectPromise(result, promiseCapability).
  9. Return ! result.
Note

This function requires its this value to be a constructor function that supports the parameter conventions of the Promise constructor.

27.2.4.2.1 PerformPromiseAllSettled ( iteratorRecord, constructor, resultCapability, promiseResolve )

The abstract operation PerformPromiseAllSettled takes arguments iteratorRecord (an Iterator Record), constructor (a constructor), resultCapability (a PromiseCapability Record), and promiseResolve (a function object) and returns either a normal completion containing an ECMAScript language value or a throw completion. It performs the following steps when called:

  1. Let values be a new empty List.
  2. Let remainingElementsCount be the Record { [[Value]]: 1 }.
  3. Let index be 0.
  4. Repeat,
    1. Let next be ? IteratorStepValue(iteratorRecord).
    2. If next is done, then
      1. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
      2. If remainingElementsCount.[[Value]] = 0, then
        1. Let valuesArray be CreateArrayFromList(values).
        2. Perform ? Call(resultCapability.[[Resolve]], undefined, « valuesArray »).
      3. Return resultCapability.[[Promise]].
    3. Append undefined to values.
    4. Let nextPromise be ? Call(promiseResolve, constructor, « next »).
    5. Let stepsFulfilled be the algorithm steps defined in Promise.allSettled Resolve Element Functions.
    6. Let lengthFulfilled be the number of non-optional parameters of the function definition in Promise.allSettled Resolve Element Functions.
    7. Let onFulfilled be CreateBuiltinFunction(stepsFulfilled, lengthFulfilled, "", « [[AlreadyCalled]], [[Index]], [[Values]], [[Capability]], [[RemainingElements]] »).
    8. Let alreadyCalled be the Record { [[Value]]: false }.
    9. Set onFulfilled.[[AlreadyCalled]] to alreadyCalled.
    10. Set onFulfilled.[[Index]] to index.
    11. Set onFulfilled.[[Values]] to values.
    12. Set onFulfilled.[[Capability]] to resultCapability.
    13. Set onFulfilled.[[RemainingElements]] to remainingElementsCount.
    14. Let stepsRejected be the algorithm steps defined in Promise.allSettled Reject Element Functions.
    15. Let lengthRejected be the number of non-optional parameters of the function definition in Promise.allSettled Reject Element Functions.
    16. Let onRejected be CreateBuiltinFunction(stepsRejected, lengthRejected, "", « [[AlreadyCalled]], [[Index]], [[Values]], [[Capability]], [[RemainingElements]] »).
    17. Set onRejected.[[AlreadyCalled]] to alreadyCalled.
    18. Set onRejected.[[Index]] to index.
    19. Set onRejected.[[Values]] to values.
    20. Set onRejected.[[Capability]] to resultCapability.
    21. Set onRejected.[[RemainingElements]] to remainingElementsCount.
    22. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] + 1.
    23. Perform ? Invoke(nextPromise, "then", « onFulfilled, onRejected »).
    24. Set index to index + 1.

27.2.4.2.2 Promise.allSettled Resolve Element Functions

A Promise.allSettled resolve element function is an anonymous built-in function that is used to resolve a specific Promise.allSettled element. Each Promise.allSettled resolve element function has [[Index]], [[Values]], [[Capability]], [[RemainingElements]], and [[AlreadyCalled]] internal slots.

When a Promise.allSettled resolve element function is called with argument x, the following steps are taken:

  1. Let F be the active function object.
  2. Let alreadyCalled be F.[[AlreadyCalled]].
  3. If alreadyCalled.[[Value]] is true, return undefined.
  4. Set alreadyCalled.[[Value]] to true.
  5. Let index be F.[[Index]].
  6. Let values be F.[[Values]].
  7. Let promiseCapability be F.[[Capability]].
  8. Let remainingElementsCount be F.[[RemainingElements]].
  9. Let obj be OrdinaryObjectCreate(%Object.prototype%).
  10. Perform ! CreateDataPropertyOrThrow(obj, "status", "fulfilled").
  11. Perform ! CreateDataPropertyOrThrow(obj, "value", x).
  12. Set values[index] to obj.
  13. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
  14. If remainingElementsCount.[[Value]] = 0, then
    1. Let valuesArray be CreateArrayFromList(values).
    2. Return ? Call(promiseCapability.[[Resolve]], undefined, « valuesArray »).
  15. Return undefined.

The "length" property of a Promise.allSettled resolve element function is 1𝔽.

27.2.4.2.3 Promise.allSettled Reject Element Functions

A Promise.allSettled reject element function is an anonymous built-in function that is used to reject a specific Promise.allSettled element. Each Promise.allSettled reject element function has [[Index]], [[Values]], [[Capability]], [[RemainingElements]], and [[AlreadyCalled]] internal slots.

When a Promise.allSettled reject element function is called with argument x, the following steps are taken:

  1. Let F be the active function object.
  2. Let alreadyCalled be F.[[AlreadyCalled]].
  3. If alreadyCalled.[[Value]] is true, return undefined.
  4. Set alreadyCalled.[[Value]] to true.
  5. Let index be F.[[Index]].
  6. Let values be F.[[Values]].
  7. Let promiseCapability be F.[[Capability]].
  8. Let remainingElementsCount be F.[[RemainingElements]].
  9. Let obj be OrdinaryObjectCreate(%Object.prototype%).
  10. Perform ! CreateDataPropertyOrThrow(obj, "status", "rejected").
  11. Perform ! CreateDataPropertyOrThrow(obj, "reason", x).
  12. Set values[index] to obj.
  13. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
  14. If remainingElementsCount.[[Value]] = 0, then
    1. Let valuesArray be CreateArrayFromList(values).
    2. Return ? Call(promiseCapability.[[Resolve]], undefined, « valuesArray »).
  15. Return undefined.

The "length" property of a Promise.allSettled reject element function is 1𝔽.

27.2.4.3 Promise.any ( iterable )

This function returns a promise that is fulfilled by the first given promise to be fulfilled, or rejected with an AggregateError holding the rejection reasons if all of the given promises are rejected. It resolves all elements of the passed iterable to promises as it runs this algorithm.

  1. Let C be the this value.
  2. Let promiseCapability be ? NewPromiseCapability(C).
  3. Let promiseResolve be Completion(GetPromiseResolve(C)).
  4. IfAbruptRejectPromise(promiseResolve, promiseCapability).
  5. Let iteratorRecord be Completion(GetIterator(iterable, sync)).
  6. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
  7. Let result be Completion(PerformPromiseAny(iteratorRecord, C, promiseCapability, promiseResolve)).
  8. If result is an abrupt completion, then
    1. If iteratorRecord.[[Done]] is false, set result to Completion(IteratorClose(iteratorRecord, result)).
    2. IfAbruptRejectPromise(result, promiseCapability).
  9. Return ! result.
Note

This function requires its this value to be a constructor function that supports the parameter conventions of the Promise constructor.

27.2.4.3.1 PerformPromiseAny ( iteratorRecord, constructor, resultCapability, promiseResolve )

The abstract operation PerformPromiseAny takes arguments iteratorRecord (an Iterator Record), constructor (a constructor), resultCapability (a PromiseCapability Record), and promiseResolve (a function object) and returns either a normal completion containing an ECMAScript language value or a throw completion. It performs the following steps when called:

  1. Let errors be a new empty List.
  2. Let remainingElementsCount be the Record { [[Value]]: 1 }.
  3. Let index be 0.
  4. Repeat,
    1. Let next be ? IteratorStepValue(iteratorRecord).
    2. If next is done, then
      1. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
      2. If remainingElementsCount.[[Value]] = 0, then
        1. Let error be a newly created AggregateError object.
        2. Perform ! DefinePropertyOrThrow(error, "errors", PropertyDescriptor { [[Configurable]]: true, [[Enumerable]]: false, [[Writable]]: true, [[Value]]: CreateArrayFromList(errors) }).
        3. Return ThrowCompletion(error).
      3. Return resultCapability.[[Promise]].
    3. Append undefined to errors.
    4. Let nextPromise be ? Call(promiseResolve, constructor, « next »).
    5. Let stepsRejected be the algorithm steps defined in Promise.any Reject Element Functions.
    6. Let lengthRejected be the number of non-optional parameters of the function definition in Promise.any Reject Element Functions.
    7. Let onRejected be CreateBuiltinFunction(stepsRejected, lengthRejected, "", « [[AlreadyCalled]], [[Index]], [[Errors]], [[Capability]], [[RemainingElements]] »).
    8. Set onRejected.[[AlreadyCalled]] to false.
    9. Set onRejected.[[Index]] to index.
    10. Set onRejected.[[Errors]] to errors.
    11. Set onRejected.[[Capability]] to resultCapability.
    12. Set onRejected.[[RemainingElements]] to remainingElementsCount.
    13. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] + 1.
    14. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], onRejected »).
    15. Set index to index + 1.

27.2.4.3.2 Promise.any Reject Element Functions

A Promise.any reject element function is an anonymous built-in function that is used to reject a specific Promise.any element. Each Promise.any reject element function has [[Index]], [[Errors]], [[Capability]], [[RemainingElements]], and [[AlreadyCalled]] internal slots.

When a Promise.any reject element function is called with argument x, the following steps are taken:

  1. Let F be the active function object.
  2. If F.[[AlreadyCalled]] is true, return undefined.
  3. Set F.[[AlreadyCalled]] to true.
  4. Let index be F.[[Index]].
  5. Let errors be F.[[Errors]].
  6. Let promiseCapability be F.[[Capability]].
  7. Let remainingElementsCount be F.[[RemainingElements]].
  8. Set errors[index] to x.
  9. Set remainingElementsCount.[[Value]] to remainingElementsCount.[[Value]] - 1.
  10. If remainingElementsCount.[[Value]] = 0, then
    1. Let error be a newly created AggregateError object.
    2. Perform ! DefinePropertyOrThrow(error, "errors", PropertyDescriptor { [[Configurable]]: true, [[Enumerable]]: false, [[Writable]]: true, [[Value]]: CreateArrayFromList(errors) }).
    3. Return ? Call(promiseCapability.[[Reject]], undefined, « error »).
  11. Return undefined.

The "length" property of a Promise.any reject element function is 1𝔽.

27.2.4.4 Promise.prototype

The initial value of Promise.prototype is the Promise prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

27.2.4.5 Promise.race ( iterable )

This function returns a new promise which is settled in the same way as the first passed promise to settle. It resolves all elements of the passed iterable to promises as it runs this algorithm.

  1. Let C be the this value.
  2. Let promiseCapability be ? NewPromiseCapability(C).
  3. Let promiseResolve be Completion(GetPromiseResolve(C)).
  4. IfAbruptRejectPromise(promiseResolve, promiseCapability).
  5. Let iteratorRecord be Completion(GetIterator(iterable, sync)).
  6. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
  7. Let result be Completion(PerformPromiseRace(iteratorRecord, C, promiseCapability, promiseResolve)).
  8. If result is an abrupt completion, then
    1. If iteratorRecord.[[Done]] is false, set result to Completion(IteratorClose(iteratorRecord, result)).
    2. IfAbruptRejectPromise(result, promiseCapability).
  9. Return ! result.
Note 1

If the iterable argument yields no values or if none of the promises yielded by iterable ever settle, then the pending promise returned by this method will never be settled.

Note 2

This function expects its this value to be a constructor function that supports the parameter conventions of the Promise constructor. It also expects that its this value provides a resolve method.

27.2.4.5.1 PerformPromiseRace ( iteratorRecord, constructor, resultCapability, promiseResolve )

The abstract operation PerformPromiseRace takes arguments iteratorRecord (an Iterator Record), constructor (a constructor), resultCapability (a PromiseCapability Record), and promiseResolve (a function object) and returns either a normal completion containing an ECMAScript language value or a throw completion. It performs the following steps when called:

  1. Repeat,
    1. Let next be ? IteratorStepValue(iteratorRecord).
    2. If next is done, then
      1. Return resultCapability.[[Promise]].
    3. Let nextPromise be ? Call(promiseResolve, constructor, « next »).
    4. Perform ? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], resultCapability.[[Reject]] »).

27.2.4.6 Promise.reject ( r )

This function returns a new promise rejected with the passed argument.

  1. Let C be the this value.
  2. Let promiseCapability be ? NewPromiseCapability(C).
  3. Perform ? Call(promiseCapability.[[Reject]], undefined, « r »).
  4. Return promiseCapability.[[Promise]].
Note

This function expects its this value to be a constructor function that supports the parameter conventions of the Promise constructor.

27.2.4.7 Promise.resolve ( x )

This function returns either a new promise resolved with the passed argument, or the argument itself if the argument is a promise produced by this constructor.

  1. Let C be the this value.
  2. If C is not an Object, throw a TypeError exception.
  3. Return ? PromiseResolve(C, x).
Note

This function expects its this value to be a constructor function that supports the parameter conventions of the Promise constructor.

27.2.4.7.1 PromiseResolve ( C, x )

The abstract operation PromiseResolve takes arguments C (an Object) and x (an ECMAScript language value) and returns either a normal completion containing an ECMAScript language value or a throw completion. It returns a new promise resolved with x. It performs the following steps when called:

  1. If IsPromise(x) is true, then
    1. Let xConstructor be ? Get(x, "constructor").
    2. If SameValue(xConstructor, C) is true, return x.
  2. Let promiseCapability be ? NewPromiseCapability(C).
  3. Perform ? Call(promiseCapability.[[Resolve]], undefined, « x »).
  4. Return promiseCapability.[[Promise]].

27.2.4.8 Promise.try ( callback, ...args )

This function performs the following steps when called:

  1. Let C be the this value.
  2. If C is not an Object, throw a TypeError exception.
  3. Let promiseCapability be ? NewPromiseCapability(C).
  4. Let status be Completion(Call(callback, undefined, args)).
  5. If status is an abrupt completion, then
    1. Perform ? Call(promiseCapability.[[Reject]], undefined, « status.[[Value]] »).
  6. Else,
    1. Perform ? Call(promiseCapability.[[Resolve]], undefined, « status.[[Value]] »).
  7. Return promiseCapability.[[Promise]].
Note

This function expects its this value to be a constructor function that supports the parameter conventions of the Promise constructor.

27.2.4.9 Promise.withResolvers ( )

This function returns an object with three properties: a new promise together with the resolve and reject functions associated with it.

  1. Let C be the this value.
  2. Let promiseCapability be ? NewPromiseCapability(C).
  3. Let obj be OrdinaryObjectCreate(%Object.prototype%).
  4. Perform ! CreateDataPropertyOrThrow(obj, "promise", promiseCapability.[[Promise]]).
  5. Perform ! CreateDataPropertyOrThrow(obj, "resolve", promiseCapability.[[Resolve]]).
  6. Perform ! CreateDataPropertyOrThrow(obj, "reject", promiseCapability.[[Reject]]).
  7. Return obj.

27.2.4.10 get Promise [ %Symbol.species% ]

Promise[%Symbol.species%] is an accessor property whose set accessor function is undefined. Its get accessor function performs the following steps when called:

  1. Return the this value.

The value of the "name" property of this function is "get [Symbol.species]".

Note

Promise prototype methods normally use their this value's constructor to create a derived object. However, a subclass constructor may over-ride that default behaviour by redefining its %Symbol.species% property.

27.2.5 Properties of the Promise Prototype Object

The Promise prototype object:

  • is %Promise.prototype%.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.
  • is an ordinary object.
  • does not have a [[PromiseState]] internal slot or any of the other internal slots of Promise instances.

27.2.5.1 Promise.prototype.catch ( onRejected )

This method performs the following steps when called:

  1. Let promise be the this value.
  2. Return ? Invoke(promise, "then", « undefined, onRejected »).

27.2.5.2 Promise.prototype.constructor

The initial value of Promise.prototype.constructor is %Promise%.

27.2.5.3 Promise.prototype.finally ( onFinally )

This method performs the following steps when called:

  1. Let promise be the this value.
  2. If promise is not an Object, throw a TypeError exception.
  3. Let C be ? SpeciesConstructor(promise, %Promise%).
  4. Assert: IsConstructor(C) is true.
  5. If IsCallable(onFinally) is false, then
    1. Let thenFinally be onFinally.
    2. Let catchFinally be onFinally.
  6. Else,
    1. Let thenFinallyClosure be a new Abstract Closure with parameters (value) that captures onFinally and C and performs the following steps when called:
      1. Let result be ? Call(onFinally, undefined).
      2. Let p be ? PromiseResolve(C, result).
      3. Let returnValue be a new Abstract Closure with no parameters that captures value and performs the following steps when called:
        1. Return NormalCompletion(value).
      4. Let valueThunk be CreateBuiltinFunction(returnValue, 0, "", « »).
      5. Return ? Invoke(p, "then", « valueThunk »).
    2. Let thenFinally be CreateBuiltinFunction(thenFinallyClosure, 1, "", « »).
    3. Let catchFinallyClosure be a new Abstract Closure with parameters (reason) that captures onFinally and C and performs the following steps when called:
      1. Let result be ? Call(onFinally, undefined).
      2. Let p be ? PromiseResolve(C, result).
      3. Let throwReason be a new Abstract Closure with no parameters that captures reason and performs the following steps when called:
        1. Return ThrowCompletion(reason).
      4. Let thrower be CreateBuiltinFunction(throwReason, 0, "", « »).
      5. Return ? Invoke(p, "then", « thrower »).
    4. Let catchFinally be CreateBuiltinFunction(catchFinallyClosure, 1, "", « »).
  7. Return ? Invoke(promise, "then", « thenFinally, catchFinally »).

27.2.5.4 Promise.prototype.then ( onFulfilled, onRejected )

This method performs the following steps when called:

  1. Let promise be the this value.
  2. If IsPromise(promise) is false, throw a TypeError exception.
  3. Let C be ? SpeciesConstructor(promise, %Promise%).
  4. Let resultCapability be ? NewPromiseCapability(C).
  5. Return PerformPromiseThen(promise, onFulfilled, onRejected, resultCapability).

27.2.5.4.1 PerformPromiseThen ( promise, onFulfilled, onRejected [ , resultCapability ] )

The abstract operation PerformPromiseThen takes arguments promise (a Promise), onFulfilled (an ECMAScript language value), and onRejected (an ECMAScript language value) and optional argument resultCapability (a PromiseCapability Record) and returns an ECMAScript language value. It performs the “then” operation on promise using onFulfilled and onRejected as its settlement actions. If resultCapability is passed, the result is stored by updating resultCapability's promise. If it is not passed, then PerformPromiseThen is being called by a specification-internal operation where the result does not matter. It performs the following steps when called:

  1. Assert: IsPromise(promise) is true.
  2. If resultCapability is not present, then
    1. Set resultCapability to undefined.
  3. If IsCallable(onFulfilled) is false, then
    1. Let onFulfilledJobCallback be empty.
  4. Else,
    1. Let onFulfilledJobCallback be HostMakeJobCallback(onFulfilled).
  5. If IsCallable(onRejected) is false, then
    1. Let onRejectedJobCallback be empty.
  6. Else,
    1. Let onRejectedJobCallback be HostMakeJobCallback(onRejected).
  7. Let fulfillReaction be the PromiseReaction Record { [[Capability]]: resultCapability, [[Type]]: fulfill, [[Handler]]: onFulfilledJobCallback }.
  8. Let rejectReaction be the PromiseReaction Record { [[Capability]]: resultCapability, [[Type]]: reject, [[Handler]]: onRejectedJobCallback }.
  9. If promise.[[PromiseState]] is pending, then
    1. Append fulfillReaction to promise.[[PromiseFulfillReactions]].
    2. Append rejectReaction to promise.[[PromiseRejectReactions]].
  10. Else if promise.[[PromiseState]] is fulfilled, then
    1. Let value be promise.[[PromiseResult]].
    2. Let fulfillJob be NewPromiseReactionJob(fulfillReaction, value).
    3. Perform HostEnqueuePromiseJob(fulfillJob.[[Job]], fulfillJob.[[Realm]]).
  11. Else,
    1. Assert: promise.[[PromiseState]] is rejected.
    2. Let reason be promise.[[PromiseResult]].
    3. If promise.[[PromiseIsHandled]] is false, perform HostPromiseRejectionTracker(promise, "handle").
    4. Let rejectJob be NewPromiseReactionJob(rejectReaction, reason).
    5. Perform HostEnqueuePromiseJob(rejectJob.[[Job]], rejectJob.[[Realm]]).
  12. Set promise.[[PromiseIsHandled]] to true.
  13. If resultCapability is undefined, then
    1. Return undefined.
  14. Else,
    1. Return resultCapability.[[Promise]].

27.2.5.5 Promise.prototype [ %Symbol.toStringTag% ]

The initial value of the %Symbol.toStringTag% property is the String value "Promise".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

27.2.6 Properties of Promise Instances

Promise instances are ordinary objects that inherit properties from the Promise prototype object (the intrinsic, %Promise.prototype%). Promise instances are initially created with the internal slots described in Table 92.

Table 92: Internal Slots of Promise Instances
Internal Slot Type Description
[[PromiseState]] pending, fulfilled, or rejected Governs how a promise will react to incoming calls to its then method.
[[PromiseResult]] an ECMAScript language value or empty The value with which the promise has been fulfilled or rejected, if any. empty if and only if the [[PromiseState]] is pending.
[[PromiseFulfillReactions]] a List of PromiseReaction Records Records to be processed when/if the promise transitions from the pending state to the fulfilled state.
[[PromiseRejectReactions]] a List of PromiseReaction Records Records to be processed when/if the promise transitions from the pending state to the rejected state.
[[PromiseIsHandled]] a Boolean Indicates whether the promise has ever had a fulfillment or rejection handler; used in unhandled rejection tracking.

27.3 GeneratorFunction Objects

GeneratorFunctions are functions that are usually created by evaluating GeneratorDeclarations, GeneratorExpressions, and GeneratorMethods. They may also be created by calling the %GeneratorFunction% intrinsic.

Figure 6 (Informative): Generator Objects Relationships
A staggering variety of boxes and arrows.

27.3.1 The GeneratorFunction Constructor

The GeneratorFunction constructor:

  • is %GeneratorFunction%.
  • is a subclass of Function.
  • creates and initializes a new GeneratorFunction when called as a function rather than as a constructor. Thus the function call GeneratorFunction (…) is equivalent to the object creation expression new GeneratorFunction (…) with the same arguments.
  • may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified GeneratorFunction behaviour must include a super call to the GeneratorFunction constructor to create and initialize subclass instances with the internal slots necessary for built-in GeneratorFunction behaviour. All ECMAScript syntactic forms for defining generator function objects create direct instances of GeneratorFunction. There is no syntactic means to create instances of GeneratorFunction subclasses.

27.3.1.1 GeneratorFunction ( ...parameterArgs, bodyArg )

The last argument (if any) specifies the body (executable code) of a generator function; any preceding arguments specify formal parameters.

This function performs the following steps when called:

  1. Let C be the active function object.
  2. If bodyArg is not present, set bodyArg to the empty String.
  3. Return ? CreateDynamicFunction(C, NewTarget, generator, parameterArgs, bodyArg).
Note

See NOTE for 20.2.1.1.

27.3.2 Properties of the GeneratorFunction Constructor

The GeneratorFunction constructor:

  • is a standard built-in function object that inherits from the Function constructor.
  • has a [[Prototype]] internal slot whose value is %Function%.
  • has a "length" property whose value is 1𝔽.
  • has a "name" property whose value is "GeneratorFunction".
  • has the following properties:

27.3.2.1 GeneratorFunction.prototype

The initial value of GeneratorFunction.prototype is the GeneratorFunction prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

27.3.3 Properties of the GeneratorFunction Prototype Object

The GeneratorFunction prototype object:

27.3.3.1 GeneratorFunction.prototype.constructor

The initial value of GeneratorFunction.prototype.constructor is %GeneratorFunction%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

27.3.3.2 GeneratorFunction.prototype.prototype

The initial value of GeneratorFunction.prototype.prototype is %GeneratorPrototype%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

27.3.3.3 GeneratorFunction.prototype [ %Symbol.toStringTag% ]

The initial value of the %Symbol.toStringTag% property is the String value "GeneratorFunction".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

27.3.4 GeneratorFunction Instances

Every GeneratorFunction instance is an ECMAScript function object and has the internal slots listed in Table 30. The value of the [[IsClassConstructor]] internal slot for all such instances is false.

Each GeneratorFunction instance has the following own properties:

27.3.4.1 length

The specification for the "length" property of Function instances given in 20.2.4.1 also applies to GeneratorFunction instances.

27.3.4.2 name

The specification for the "name" property of Function instances given in 20.2.4.2 also applies to GeneratorFunction instances.

27.3.4.3 prototype

Whenever a GeneratorFunction instance is created another ordinary object is also created and is the initial value of the generator function's "prototype" property. The value of the prototype property is used to initialize the [[Prototype]] internal slot of a newly created Generator when the generator function object is invoked using [[Call]].

This property has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }.

Note

Unlike Function instances, the object that is the value of a GeneratorFunction's "prototype" property does not have a "constructor" property whose value is the GeneratorFunction instance.

27.4 AsyncGeneratorFunction Objects

AsyncGeneratorFunctions are functions that are usually created by evaluating AsyncGeneratorDeclaration, AsyncGeneratorExpression, and AsyncGeneratorMethod syntactic productions. They may also be created by calling the %AsyncGeneratorFunction% intrinsic.

27.4.1 The AsyncGeneratorFunction Constructor

The AsyncGeneratorFunction constructor:

  • is %AsyncGeneratorFunction%.
  • is a subclass of Function.
  • creates and initializes a new AsyncGeneratorFunction when called as a function rather than as a constructor. Thus the function call AsyncGeneratorFunction (...) is equivalent to the object creation expression new AsyncGeneratorFunction (...) with the same arguments.
  • may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified AsyncGeneratorFunction behaviour must include a super call to the AsyncGeneratorFunction constructor to create and initialize subclass instances with the internal slots necessary for built-in AsyncGeneratorFunction behaviour. All ECMAScript syntactic forms for defining async generator function objects create direct instances of AsyncGeneratorFunction. There is no syntactic means to create instances of AsyncGeneratorFunction subclasses.

27.4.1.1 AsyncGeneratorFunction ( ...parameterArgs, bodyArg )

The last argument (if any) specifies the body (executable code) of an async generator function; any preceding arguments specify formal parameters.

This function performs the following steps when called:

  1. Let C be the active function object.
  2. If bodyArg is not present, set bodyArg to the empty String.
  3. Return ? CreateDynamicFunction(C, NewTarget, async-generator, parameterArgs, bodyArg).
Note

See NOTE for 20.2.1.1.

27.4.2 Properties of the AsyncGeneratorFunction Constructor

The AsyncGeneratorFunction constructor:

  • is a standard built-in function object that inherits from the Function constructor.
  • has a [[Prototype]] internal slot whose value is %Function%.
  • has a "length" property whose value is 1𝔽.
  • has a "name" property whose value is "AsyncGeneratorFunction".
  • has the following properties:

27.4.2.1 AsyncGeneratorFunction.prototype

The initial value of AsyncGeneratorFunction.prototype is the AsyncGeneratorFunction prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

27.4.3 Properties of the AsyncGeneratorFunction Prototype Object

The AsyncGeneratorFunction prototype object:

27.4.3.1 AsyncGeneratorFunction.prototype.constructor

The initial value of AsyncGeneratorFunction.prototype.constructor is %AsyncGeneratorFunction%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

27.4.3.2 AsyncGeneratorFunction.prototype.prototype

The initial value of AsyncGeneratorFunction.prototype.prototype is %AsyncGeneratorPrototype%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

27.4.3.3 AsyncGeneratorFunction.prototype [ %Symbol.toStringTag% ]

The initial value of the %Symbol.toStringTag% property is the String value "AsyncGeneratorFunction".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

27.4.4 AsyncGeneratorFunction Instances

Every AsyncGeneratorFunction instance is an ECMAScript function object and has the internal slots listed in Table 30. The value of the [[IsClassConstructor]] internal slot for all such instances is false.

Each AsyncGeneratorFunction instance has the following own properties:

27.4.4.1 length

The value of the "length" property is an integral Number that indicates the typical number of arguments expected by the AsyncGeneratorFunction. However, the language permits the function to be invoked with some other number of arguments. The behaviour of an AsyncGeneratorFunction when invoked on a number of arguments other than the number specified by its "length" property depends on the function.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

27.4.4.2 name

The specification for the "name" property of Function instances given in 20.2.4.2 also applies to AsyncGeneratorFunction instances.

27.4.4.3 prototype

Whenever an AsyncGeneratorFunction instance is created, another ordinary object is also created and is the initial value of the async generator function's "prototype" property. The value of the prototype property is used to initialize the [[Prototype]] internal slot of a newly created AsyncGenerator when the generator function object is invoked using [[Call]].

This property has the attributes { [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false }.

Note

Unlike function instances, the object that is the value of an AsyncGeneratorFunction's "prototype" property does not have a "constructor" property whose value is the AsyncGeneratorFunction instance.

27.5 Generator Objects

A Generator is created by calling a generator function and conforms to both the iterator interface and the iterable interface.

Generator instances directly inherit properties from the initial value of the "prototype" property of the generator function that created the instance. Generator instances indirectly inherit properties from %GeneratorPrototype%.

27.5.1 The %GeneratorPrototype% Object

The %GeneratorPrototype% object:

  • is %GeneratorFunction.prototype.prototype%.
  • is an ordinary object.
  • is not a Generator instance and does not have a [[GeneratorState]] internal slot.
  • has a [[Prototype]] internal slot whose value is %Iterator.prototype%.
  • has properties that are indirectly inherited by all Generator instances.

27.5.1.1 %GeneratorPrototype%.constructor

The initial value of %GeneratorPrototype%.constructor is %GeneratorFunction.prototype%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

27.5.1.2 %GeneratorPrototype%.next ( value )

  1. Return ? GeneratorResume(this value, value, empty).

27.5.1.3 %GeneratorPrototype%.return ( value )

This method performs the following steps when called:

  1. Let g be the this value.
  2. Let C be ReturnCompletion(value).
  3. Return ? GeneratorResumeAbrupt(g, C, empty).

27.5.1.4 %GeneratorPrototype%.throw ( exception )

This method performs the following steps when called:

  1. Let g be the this value.
  2. Let C be ThrowCompletion(exception).
  3. Return ? GeneratorResumeAbrupt(g, C, empty).

27.5.1.5 %GeneratorPrototype% [ %Symbol.toStringTag% ]

The initial value of the %Symbol.toStringTag% property is the String value "Generator".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

27.5.2 Properties of Generator Instances

Generator instances are initially created with the internal slots described in Table 93.

Table 93: Internal Slots of Generator Instances
Internal Slot Type Description
[[GeneratorState]] suspended-start, suspended-yield, executing, or completed The current execution state of the generator.
[[GeneratorContext]] an execution context The execution context that is used when executing the code of this generator.
[[GeneratorBrand]] a String or empty A brand used to distinguish different kinds of generators. The [[GeneratorBrand]] of generators declared by ECMAScript source text is always empty.

27.5.3 Generator Abstract Operations

27.5.3.1 GeneratorStart ( generator, generatorBody )

The abstract operation GeneratorStart takes arguments generator (a Generator) and generatorBody (a FunctionBody Parse Node or an Abstract Closure with no parameters) and returns unused. It performs the following steps when called:

  1. Assert: generator.[[GeneratorState]] is suspended-start.
  2. Let genContext be the running execution context.
  3. Set the Generator component of genContext to generator.
  4. Let closure be a new Abstract Closure with no parameters that captures generatorBody and performs the following steps when called:
    1. Let acGenContext be the running execution context.
    2. Let acGenerator be the Generator component of acGenContext.
    3. If generatorBody is a Parse Node, then
      1. Let result be Completion(Evaluation of generatorBody).
    4. Else,
      1. Assert: generatorBody is an Abstract Closure with no parameters.
      2. Let result be Completion(generatorBody()).
    5. Assert: If we return here, the generator either threw an exception or performed either an implicit or explicit return.
    6. Remove acGenContext from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context.
    7. Set acGenerator.[[GeneratorState]] to completed.
    8. NOTE: Once a generator enters the completed state it never leaves it and its associated execution context is never resumed. Any execution state associated with acGenerator can be discarded at this point.
    9. If result is a normal completion, then
      1. Let resultValue be undefined.
    10. Else if result is a return completion, then
      1. Let resultValue be result.[[Value]].
    11. Else,
      1. Assert: result is a throw completion.
      2. Return ? result.
    12. Return NormalCompletion(CreateIteratorResultObject(resultValue, true)).
  5. Set the code evaluation state of genContext such that when evaluation is resumed for that execution context, closure will be called with no arguments.
  6. Set generator.[[GeneratorContext]] to genContext.
  7. Return unused.

27.5.3.2 GeneratorValidate ( generator, generatorBrand )

The abstract operation GeneratorValidate takes arguments generator (an ECMAScript language value) and generatorBrand (a String or empty) and returns either a normal completion containing one of suspended-start, suspended-yield, or completed, or a throw completion. It performs the following steps when called:

  1. Perform ? RequireInternalSlot(generator, [[GeneratorState]]).
  2. Perform ? RequireInternalSlot(generator, [[GeneratorBrand]]).
  3. If generator.[[GeneratorBrand]] is not generatorBrand, throw a TypeError exception.
  4. Assert: generator also has a [[GeneratorContext]] internal slot.
  5. Let state be generator.[[GeneratorState]].
  6. If state is executing, throw a TypeError exception.
  7. Return state.

27.5.3.3 GeneratorResume ( generator, value, generatorBrand )

The abstract operation GeneratorResume takes arguments generator (an ECMAScript language value), value (an ECMAScript language value or empty), and generatorBrand (a String or empty) and returns either a normal completion containing an ECMAScript language value or a throw completion. It performs the following steps when called:

  1. Let state be ? GeneratorValidate(generator, generatorBrand).
  2. If state is completed, return CreateIteratorResultObject(undefined, true).
  3. Assert: state is either suspended-start or suspended-yield.
  4. Let genContext be generator.[[GeneratorContext]].
  5. Let methodContext be the running execution context.
  6. Suspend methodContext.
  7. Set generator.[[GeneratorState]] to executing.
  8. Push genContext onto the execution context stack; genContext is now the running execution context.
  9. Resume the suspended evaluation of genContext using NormalCompletion(value) as the result of the operation that suspended it. Let result be the value returned by the resumed computation.
  10. Assert: When we return here, genContext has already been removed from the execution context stack and methodContext is the currently running execution context.
  11. Return ? result.

27.5.3.4 GeneratorResumeAbrupt ( generator, abruptCompletion, generatorBrand )

The abstract operation GeneratorResumeAbrupt takes arguments generator (an ECMAScript language value), abruptCompletion (a return completion or a throw completion), and generatorBrand (a String or empty) and returns either a normal completion containing an ECMAScript language value or a throw completion. It performs the following steps when called:

  1. Let state be ? GeneratorValidate(generator, generatorBrand).
  2. If state is suspended-start, then
    1. Set generator.[[GeneratorState]] to completed.
    2. NOTE: Once a generator enters the completed state it never leaves it and its associated execution context is never resumed. Any execution state associated with generator can be discarded at this point.
    3. Set state to completed.
  3. If state is completed, then
    1. If abruptCompletion is a return completion, then
      1. Return CreateIteratorResultObject(abruptCompletion.[[Value]], true).
    2. Return ? abruptCompletion.
  4. Assert: state is suspended-yield.
  5. Let genContext be generator.[[GeneratorContext]].
  6. Let methodContext be the running execution context.
  7. Suspend methodContext.
  8. Set generator.[[GeneratorState]] to executing.
  9. Push genContext onto the execution context stack; genContext is now the running execution context.
  10. Resume the suspended evaluation of genContext using abruptCompletion as the result of the operation that suspended it. Let result be the Completion Record returned by the resumed computation.
  11. Assert: When we return here, genContext has already been removed from the execution context stack and methodContext is the currently running execution context.
  12. Return ? result.

27.5.3.5 GetGeneratorKind ( )

The abstract operation GetGeneratorKind takes no arguments and returns non-generator, sync, or async. It performs the following steps when called:

  1. Let genContext be the running execution context.
  2. If genContext does not have a Generator component, return non-generator.
  3. Let generator be the Generator component of genContext.
  4. If generator has an [[AsyncGeneratorState]] internal slot, return async.
  5. Else, return sync.

27.5.3.6 GeneratorYield ( iteratorResult )

The abstract operation GeneratorYield takes argument iteratorResult (an Object that conforms to the IteratorResult interface) and returns either a normal completion containing an ECMAScript language value or an abrupt completion. It performs the following steps when called:

  1. Let genContext be the running execution context.
  2. Assert: genContext is the execution context of a generator.
  3. Let generator be the value of the Generator component of genContext.
  4. Assert: GetGeneratorKind() is sync.
  5. Set generator.[[GeneratorState]] to suspended-yield.
  6. Remove genContext from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context.
  7. Let callerContext be the running execution context.
  8. Resume callerContext passing NormalCompletion(iteratorResult). If genContext is ever resumed again, let resumptionValue be the Completion Record with which it is resumed.
  9. Assert: If control reaches here, then genContext is the running execution context again.
  10. Return resumptionValue.

27.5.3.7 Yield ( value )

The abstract operation Yield takes argument value (an ECMAScript language value) and returns either a normal completion containing an ECMAScript language value or an abrupt completion. It performs the following steps when called:

  1. Let generatorKind be GetGeneratorKind().
  2. If generatorKind is async, return ? AsyncGeneratorYield(? Await(value)).
  3. Otherwise, return ? GeneratorYield(CreateIteratorResultObject(value, false)).

27.5.3.8 CreateIteratorFromClosure ( closure, generatorBrand, generatorPrototype [ , extraSlots ] )

The abstract operation CreateIteratorFromClosure takes arguments closure (an Abstract Closure with no parameters), generatorBrand (a String or empty), and generatorPrototype (an Object) and optional argument extraSlots (a List of names of internal slots) and returns a Generator. It performs the following steps when called:

  1. NOTE: closure can contain uses of the Yield operation to yield an IteratorResult object.
  2. If extraSlots is not present, set extraSlots to a new empty List.
  3. Let internalSlotsList be the list-concatenation of extraSlots and « [[GeneratorState]], [[GeneratorContext]], [[GeneratorBrand]] ».
  4. Let generator be OrdinaryObjectCreate(generatorPrototype, internalSlotsList).
  5. Set generator.[[GeneratorBrand]] to generatorBrand.
  6. Set generator.[[GeneratorState]] to suspended-start.
  7. Let callerContext be the running execution context.
  8. Let calleeContext be a new execution context.
  9. Set the Function of calleeContext to null.
  10. Set the Realm of calleeContext to the current Realm Record.
  11. Set the ScriptOrModule of calleeContext to callerContext's ScriptOrModule.
  12. If callerContext is not already suspended, suspend callerContext.
  13. Push calleeContext onto the execution context stack; calleeContext is now the running execution context.
  14. Perform GeneratorStart(generator, closure).
  15. Remove calleeContext from the execution context stack and restore callerContext as the running execution context.
  16. Return generator.

27.6 AsyncGenerator Objects

An AsyncGenerator is created by calling an async generator function and conforms to both the async iterator interface and the async iterable interface.

AsyncGenerator instances directly inherit properties from the initial value of the "prototype" property of the async generator function that created the instance. AsyncGenerator instances indirectly inherit properties from %AsyncGeneratorPrototype%.

27.6.1 The %AsyncGeneratorPrototype% Object

The %AsyncGeneratorPrototype% object:

  • is %AsyncGeneratorFunction.prototype.prototype%.
  • is an ordinary object.
  • is not an AsyncGenerator instance and does not have an [[AsyncGeneratorState]] internal slot.
  • has a [[Prototype]] internal slot whose value is %AsyncIteratorPrototype%.
  • has properties that are indirectly inherited by all AsyncGenerator instances.

27.6.1.1 %AsyncGeneratorPrototype%.constructor

The initial value of %AsyncGeneratorPrototype%.constructor is %AsyncGeneratorFunction.prototype%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

27.6.1.2 %AsyncGeneratorPrototype%.next ( value )

  1. Let generator be the this value.
  2. Let promiseCapability be ! NewPromiseCapability(%Promise%).
  3. Let result be Completion(AsyncGeneratorValidate(generator, empty)).
  4. IfAbruptRejectPromise(result, promiseCapability).
  5. Let state be generator.[[AsyncGeneratorState]].
  6. If state is completed, then
    1. Let iteratorResult be CreateIteratorResultObject(undefined, true).
    2. Perform ! Call(promiseCapability.[[Resolve]], undefined, « iteratorResult »).
    3. Return promiseCapability.[[Promise]].
  7. Let completion be NormalCompletion(value).
  8. Perform AsyncGeneratorEnqueue(generator, completion, promiseCapability).
  9. If state is either suspended-start or suspended-yield, then
    1. Perform AsyncGeneratorResume(generator, completion).
  10. Else,
    1. Assert: state is either executing or draining-queue.
  11. Return promiseCapability.[[Promise]].

27.6.1.3 %AsyncGeneratorPrototype%.return ( value )

  1. Let generator be the this value.
  2. Let promiseCapability be ! NewPromiseCapability(%Promise%).
  3. Let result be Completion(AsyncGeneratorValidate(generator, empty)).
  4. IfAbruptRejectPromise(result, promiseCapability).
  5. Let completion be ReturnCompletion(value).
  6. Perform AsyncGeneratorEnqueue(generator, completion, promiseCapability).
  7. Let state be generator.[[AsyncGeneratorState]].
  8. If state is either suspended-start or completed, then
    1. Set generator.[[AsyncGeneratorState]] to draining-queue.
    2. Perform AsyncGeneratorAwaitReturn(generator).
  9. Else if state is suspended-yield, then
    1. Perform AsyncGeneratorResume(generator, completion).
  10. Else,
    1. Assert: state is either executing or draining-queue.
  11. Return promiseCapability.[[Promise]].

27.6.1.4 %AsyncGeneratorPrototype%.throw ( exception )

  1. Let generator be the this value.
  2. Let promiseCapability be ! NewPromiseCapability(%Promise%).
  3. Let result be Completion(AsyncGeneratorValidate(generator, empty)).
  4. IfAbruptRejectPromise(result, promiseCapability).
  5. Let state be generator.[[AsyncGeneratorState]].
  6. If state is suspended-start, then
    1. Set generator.[[AsyncGeneratorState]] to completed.
    2. Set state to completed.
  7. If state is completed, then
    1. Perform ! Call(promiseCapability.[[Reject]], undefined, « exception »).
    2. Return promiseCapability.[[Promise]].
  8. Let completion be ThrowCompletion(exception).
  9. Perform AsyncGeneratorEnqueue(generator, completion, promiseCapability).
  10. If state is suspended-yield, then
    1. Perform AsyncGeneratorResume(generator, completion).
  11. Else,
    1. Assert: state is either executing or draining-queue.
  12. Return promiseCapability.[[Promise]].

27.6.1.5 %AsyncGeneratorPrototype% [ %Symbol.toStringTag% ]

The initial value of the %Symbol.toStringTag% property is the String value "AsyncGenerator".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

27.6.2 Properties of AsyncGenerator Instances

AsyncGenerator instances are initially created with the internal slots described below:

Table 94: Internal Slots of AsyncGenerator Instances
Internal Slot Type Description
[[AsyncGeneratorState]] suspended-start, suspended-yield, executing, draining-queue, or completed The current execution state of the async generator.
[[AsyncGeneratorContext]] an execution context The execution context that is used when executing the code of this async generator.
[[AsyncGeneratorQueue]] a List of AsyncGeneratorRequest Records Records which represent requests to resume the async generator. Except during state transitions, it is non-empty if and only if [[AsyncGeneratorState]] is either executing or draining-queue.
[[GeneratorBrand]] a String or empty A brand used to distinguish different kinds of async generators. The [[GeneratorBrand]] of async generators declared by ECMAScript source text is always empty.

27.6.3 AsyncGenerator Abstract Operations

27.6.3.1 AsyncGeneratorRequest Records

An AsyncGeneratorRequest is a Record value used to store information about how an async generator should be resumed and contains capabilities for fulfilling or rejecting the corresponding promise.

They have the following fields:

Table 95: AsyncGeneratorRequest Record Fields
Field Name Value Meaning
[[Completion]] a Completion Record The Completion Record which should be used to resume the async generator.
[[Capability]] a PromiseCapability Record The promise capabilities associated with this request.

27.6.3.2 AsyncGeneratorStart ( generator, generatorBody )

The abstract operation AsyncGeneratorStart takes arguments generator (an AsyncGenerator) and generatorBody (a FunctionBody Parse Node or an Abstract Closure with no parameters) and returns unused. It performs the following steps when called:

  1. Assert: generator.[[AsyncGeneratorState]] is suspended-start.
  2. Let genContext be the running execution context.
  3. Set the Generator component of genContext to generator.
  4. Let closure be a new Abstract Closure with no parameters that captures generatorBody and performs the following steps when called:
    1. Let acGenContext be the running execution context.
    2. Let acGenerator be the Generator component of acGenContext.
    3. If generatorBody is a Parse Node, then
      1. Let result be Completion(Evaluation of generatorBody).
    4. Else,
      1. Assert: generatorBody is an Abstract Closure with no parameters.
      2. Let result be Completion(generatorBody()).
    5. Assert: If we return here, the async generator either threw an exception or performed either an implicit or explicit return.
    6. Remove acGenContext from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context.
    7. Set acGenerator.[[AsyncGeneratorState]] to draining-queue.
    8. If result is a normal completion, set result to NormalCompletion(undefined).
    9. If result is a return completion, set result to NormalCompletion(result.[[Value]]).
    10. Perform AsyncGeneratorCompleteStep(acGenerator, result, true).
    11. Perform AsyncGeneratorDrainQueue(acGenerator).
    12. Return NormalCompletion(undefined).
  5. Set the code evaluation state of genContext such that when evaluation is resumed for that execution context, closure will be called with no arguments.
  6. Set generator.[[AsyncGeneratorContext]] to genContext.
  7. Set generator.[[AsyncGeneratorQueue]] to a new empty List.
  8. Return unused.

27.6.3.3 AsyncGeneratorValidate ( generator, generatorBrand )

The abstract operation AsyncGeneratorValidate takes arguments generator (an ECMAScript language value) and generatorBrand (a String or empty) and returns either a normal completion containing unused or a throw completion. It performs the following steps when called:

  1. Perform ? RequireInternalSlot(generator, [[AsyncGeneratorContext]]).
  2. Perform ? RequireInternalSlot(generator, [[AsyncGeneratorState]]).
  3. Perform ? RequireInternalSlot(generator, [[AsyncGeneratorQueue]]).
  4. If generator.[[GeneratorBrand]] is not generatorBrand, throw a TypeError exception.
  5. Return unused.

27.6.3.4 AsyncGeneratorEnqueue ( generator, completion, promiseCapability )

The abstract operation AsyncGeneratorEnqueue takes arguments generator (an AsyncGenerator), completion (a Completion Record), and promiseCapability (a PromiseCapability Record) and returns unused. It performs the following steps when called:

  1. Let request be AsyncGeneratorRequest { [[Completion]]: completion, [[Capability]]: promiseCapability }.
  2. Append request to generator.[[AsyncGeneratorQueue]].
  3. Return unused.

27.6.3.5 AsyncGeneratorCompleteStep ( generator, completion, done [ , realm ] )

The abstract operation AsyncGeneratorCompleteStep takes arguments generator (an AsyncGenerator), completion (a Completion Record), and done (a Boolean) and optional argument realm (a Realm Record) and returns unused. It performs the following steps when called:

  1. Assert: generator.[[AsyncGeneratorQueue]] is not empty.
  2. Let next be the first element of generator.[[AsyncGeneratorQueue]].
  3. Remove the first element from generator.[[AsyncGeneratorQueue]].
  4. Let promiseCapability be next.[[Capability]].
  5. Let value be completion.[[Value]].
  6. If completion is a throw completion, then
    1. Perform ! Call(promiseCapability.[[Reject]], undefined, « value »).
  7. Else,
    1. Assert: completion is a normal completion.
    2. If realm is present, then
      1. Let oldRealm be the running execution context's Realm.
      2. Set the running execution context's Realm to realm.
      3. Let iteratorResult be CreateIteratorResultObject(value, done).
      4. Set the running execution context's Realm to oldRealm.
    3. Else,
      1. Let iteratorResult be CreateIteratorResultObject(value, done).
    4. Perform ! Call(promiseCapability.[[Resolve]], undefined, « iteratorResult »).
  8. Return unused.

27.6.3.6 AsyncGeneratorResume ( generator, completion )

The abstract operation AsyncGeneratorResume takes arguments generator (an AsyncGenerator) and completion (a Completion Record) and returns unused. It performs the following steps when called:

  1. Assert: generator.[[AsyncGeneratorState]] is either suspended-start or suspended-yield.
  2. Let genContext be generator.[[AsyncGeneratorContext]].
  3. Let callerContext be the running execution context.
  4. Suspend callerContext.
  5. Set generator.[[AsyncGeneratorState]] to executing.
  6. Push genContext onto the execution context stack; genContext is now the running execution context.
  7. Resume the suspended evaluation of genContext using completion as the result of the operation that suspended it. Let result be the Completion Record returned by the resumed computation.
  8. Assert: result is never an abrupt completion.
  9. Assert: When we return here, genContext has already been removed from the execution context stack and callerContext is the currently running execution context.
  10. Return unused.

27.6.3.7 AsyncGeneratorUnwrapYieldResumption ( resumptionValue )

The abstract operation AsyncGeneratorUnwrapYieldResumption takes argument resumptionValue (a Completion Record) and returns either a normal completion containing an ECMAScript language value or an abrupt completion. It performs the following steps when called:

  1. If resumptionValue is not a return completion, return ? resumptionValue.
  2. Let awaited be Completion(Await(resumptionValue.[[Value]])).
  3. If awaited is a throw completion, return ? awaited.
  4. Assert: awaited is a normal completion.
  5. Return ReturnCompletion(awaited.[[Value]]).

27.6.3.8 AsyncGeneratorYield ( value )

The abstract operation AsyncGeneratorYield takes argument value (an ECMAScript language value) and returns either a normal completion containing an ECMAScript language value or an abrupt completion. It performs the following steps when called:

  1. Let genContext be the running execution context.
  2. Assert: genContext is the execution context of a generator.
  3. Let generator be the value of the Generator component of genContext.
  4. Assert: GetGeneratorKind() is async.
  5. Let completion be NormalCompletion(value).
  6. Assert: The execution context stack has at least two elements.
  7. Let previousContext be the second to top element of the execution context stack.
  8. Let previousRealm be previousContext's Realm.
  9. Perform AsyncGeneratorCompleteStep(generator, completion, false, previousRealm).
  10. Let queue be generator.[[AsyncGeneratorQueue]].
  11. If queue is not empty, then
    1. NOTE: Execution continues without suspending the generator.
    2. Let toYield be the first element of queue.
    3. Let resumptionValue be Completion(toYield.[[Completion]]).
    4. Return ? AsyncGeneratorUnwrapYieldResumption(resumptionValue).
  12. Else,
    1. Set generator.[[AsyncGeneratorState]] to suspended-yield.
    2. Remove genContext from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context.
    3. Let callerContext be the running execution context.
    4. Resume callerContext passing undefined. If genContext is ever resumed again, let resumptionValue be the Completion Record with which it is resumed.
    5. Assert: If control reaches here, then genContext is the running execution context again.
    6. Return ? AsyncGeneratorUnwrapYieldResumption(resumptionValue).

27.6.3.9 AsyncGeneratorAwaitReturn ( generator )

The abstract operation AsyncGeneratorAwaitReturn takes argument generator (an AsyncGenerator) and returns unused. It performs the following steps when called:

  1. Assert: generator.[[AsyncGeneratorState]] is draining-queue.
  2. Let queue be generator.[[AsyncGeneratorQueue]].
  3. Assert: queue is not empty.
  4. Let next be the first element of queue.
  5. Let completion be Completion(next.[[Completion]]).
  6. Assert: completion is a return completion.
  7. Let promiseCompletion be Completion(PromiseResolve(%Promise%, completion.[[Value]])).
  8. If promiseCompletion is an abrupt completion, then
    1. Perform AsyncGeneratorCompleteStep(generator, promiseCompletion, true).
    2. Perform AsyncGeneratorDrainQueue(generator).
    3. Return unused.
  9. Assert: promiseCompletion is a normal completion.
  10. Let promise be promiseCompletion.[[Value]].
  11. Let fulfilledClosure be a new Abstract Closure with parameters (value) that captures generator and performs the following steps when called:
    1. Assert: generator.[[AsyncGeneratorState]] is draining-queue.
    2. Let result be NormalCompletion(value).
    3. Perform AsyncGeneratorCompleteStep(generator, result, true).
    4. Perform AsyncGeneratorDrainQueue(generator).
    5. Return NormalCompletion(undefined).
  12. Let onFulfilled be CreateBuiltinFunction(fulfilledClosure, 1, "", « »).
  13. Let rejectedClosure be a new Abstract Closure with parameters (reason) that captures generator and performs the following steps when called:
    1. Assert: generator.[[AsyncGeneratorState]] is draining-queue.
    2. Let result be ThrowCompletion(reason).
    3. Perform AsyncGeneratorCompleteStep(generator, result, true).
    4. Perform AsyncGeneratorDrainQueue(generator).
    5. Return NormalCompletion(undefined).
  14. Let onRejected be CreateBuiltinFunction(rejectedClosure, 1, "", « »).
  15. Perform PerformPromiseThen(promise, onFulfilled, onRejected).
  16. Return unused.

27.6.3.10 AsyncGeneratorDrainQueue ( generator )

The abstract operation AsyncGeneratorDrainQueue takes argument generator (an AsyncGenerator) and returns unused. It drains the generator's AsyncGeneratorQueue until it encounters an AsyncGeneratorRequest which holds a return completion. It performs the following steps when called:

  1. Assert: generator.[[AsyncGeneratorState]] is draining-queue.
  2. Let queue be generator.[[AsyncGeneratorQueue]].
  3. Repeat, while queue is not empty,
    1. Let next be the first element of queue.
    2. Let completion be Completion(next.[[Completion]]).
    3. If completion is a return completion, then
      1. Perform AsyncGeneratorAwaitReturn(generator).
      2. Return unused.
    4. Else,
      1. If completion is a normal completion, then
        1. Set completion to NormalCompletion(undefined).
      2. Perform AsyncGeneratorCompleteStep(generator, completion, true).
  4. Set generator.[[AsyncGeneratorState]] to completed.
  5. Return unused.

27.6.3.11 CreateAsyncIteratorFromClosure ( closure, generatorBrand, generatorPrototype )

The abstract operation CreateAsyncIteratorFromClosure takes arguments closure (an Abstract Closure with no parameters), generatorBrand (a String or empty), and generatorPrototype (an Object) and returns an AsyncGenerator. It performs the following steps when called:

  1. NOTE: closure can contain uses of the Await operation and uses of the Yield operation to yield an IteratorResult object.
  2. Let internalSlotsList be « [[AsyncGeneratorState]], [[AsyncGeneratorContext]], [[AsyncGeneratorQueue]], [[GeneratorBrand]] ».
  3. Let generator be OrdinaryObjectCreate(generatorPrototype, internalSlotsList).
  4. Set generator.[[GeneratorBrand]] to generatorBrand.
  5. Set generator.[[AsyncGeneratorState]] to suspended-start.
  6. Let callerContext be the running execution context.
  7. Let calleeContext be a new execution context.
  8. Set the Function of calleeContext to null.
  9. Set the Realm of calleeContext to the current Realm Record.
  10. Set the ScriptOrModule of calleeContext to callerContext's ScriptOrModule.
  11. If callerContext is not already suspended, suspend callerContext.
  12. Push calleeContext onto the execution context stack; calleeContext is now the running execution context.
  13. Perform AsyncGeneratorStart(generator, closure).
  14. Remove calleeContext from the execution context stack and restore callerContext as the running execution context.
  15. Return generator.

27.7 AsyncFunction Objects

AsyncFunctions are functions that are usually created by evaluating AsyncFunctionDeclarations, AsyncFunctionExpressions, AsyncMethods, and AsyncArrowFunctions. They may also be created by calling the %AsyncFunction% intrinsic.

27.7.1 The AsyncFunction Constructor

The AsyncFunction constructor:

  • is %AsyncFunction%.
  • is a subclass of Function.
  • creates and initializes a new AsyncFunction when called as a function rather than as a constructor. Thus the function call AsyncFunction(…) is equivalent to the object creation expression new AsyncFunction(…) with the same arguments.
  • may be used as the value of an extends clause of a class definition. Subclass constructors that intend to inherit the specified AsyncFunction behaviour must include a super call to the AsyncFunction constructor to create and initialize a subclass instance with the internal slots necessary for built-in async function behaviour. All ECMAScript syntactic forms for defining async function objects create direct instances of AsyncFunction. There is no syntactic means to create instances of AsyncFunction subclasses.

27.7.1.1 AsyncFunction ( ...parameterArgs, bodyArg )

The last argument (if any) specifies the body (executable code) of an async function. Any preceding arguments specify formal parameters.

This function performs the following steps when called:

  1. Let C be the active function object.
  2. If bodyArg is not present, set bodyArg to the empty String.
  3. Return ? CreateDynamicFunction(C, NewTarget, async, parameterArgs, bodyArg).
Note
See NOTE for 20.2.1.1.

27.7.2 Properties of the AsyncFunction Constructor

The AsyncFunction constructor:

  • is a standard built-in function object that inherits from the Function constructor.
  • has a [[Prototype]] internal slot whose value is %Function%.
  • has a "length" property whose value is 1𝔽.
  • has a "name" property whose value is "AsyncFunction".
  • has the following properties:

27.7.2.1 AsyncFunction.prototype

The initial value of AsyncFunction.prototype is the AsyncFunction prototype object.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

27.7.3 Properties of the AsyncFunction Prototype Object

The AsyncFunction prototype object:

27.7.3.1 AsyncFunction.prototype.constructor

The initial value of AsyncFunction.prototype.constructor is %AsyncFunction%.

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

27.7.3.2 AsyncFunction.prototype [ %Symbol.toStringTag% ]

The initial value of the %Symbol.toStringTag% property is the String value "AsyncFunction".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

27.7.4 AsyncFunction Instances

Every AsyncFunction instance is an ECMAScript function object and has the internal slots listed in Table 30. The value of the [[IsClassConstructor]] internal slot for all such instances is false. AsyncFunction instances are not constructors and do not have a [[Construct]] internal method. AsyncFunction instances do not have a prototype property as they are not constructable.

Each AsyncFunction instance has the following own properties:

27.7.4.1 length

The specification for the "length" property of Function instances given in 20.2.4.1 also applies to AsyncFunction instances.

27.7.4.2 name

The specification for the "name" property of Function instances given in 20.2.4.2 also applies to AsyncFunction instances.

27.7.5 Async Functions Abstract Operations

27.7.5.1 AsyncFunctionStart ( promiseCapability, asyncFunctionBody )

The abstract operation AsyncFunctionStart takes arguments promiseCapability (a PromiseCapability Record) and asyncFunctionBody (a FunctionBody Parse Node, an ExpressionBody Parse Node, or an Abstract Closure with no parameters) and returns unused. It performs the following steps when called:

  1. Let runningContext be the running execution context.
  2. Let asyncContext be a copy of runningContext.
  3. NOTE: Copying the execution state is required for AsyncBlockStart to resume its execution. It is ill-defined to resume a currently executing context.
  4. Perform AsyncBlockStart(promiseCapability, asyncFunctionBody, asyncContext).
  5. Return unused.

27.7.5.2 AsyncBlockStart ( promiseCapability, asyncBody, asyncContext )

The abstract operation AsyncBlockStart takes arguments promiseCapability (a PromiseCapability Record), asyncBody (a Parse Node or an Abstract Closure with no parameters), and asyncContext (an execution context) and returns unused. It performs the following steps when called:

  1. Let runningContext be the running execution context.
  2. Let closure be a new Abstract Closure with no parameters that captures promiseCapability and asyncBody and performs the following steps when called:
    1. Let acAsyncContext be the running execution context.
    2. If asyncBody is a Parse Node, then
      1. Let result be Completion(Evaluation of asyncBody).
    3. Else,
      1. Assert: asyncBody is an Abstract Closure with no parameters.
      2. Let result be Completion(asyncBody()).
    4. Assert: If we return here, the async function either threw an exception or performed an implicit or explicit return; all awaiting is done.
    5. Remove acAsyncContext from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context.
    6. If result is a normal completion, then
      1. Perform ! Call(promiseCapability.[[Resolve]], undefined, « undefined »).
    7. Else if result is a return completion, then
      1. Perform ! Call(promiseCapability.[[Resolve]], undefined, « result.[[Value]] »).
    8. Else,
      1. Assert: result is a throw completion.
      2. Perform ! Call(promiseCapability.[[Reject]], undefined, « result.[[Value]] »).
    9. Return NormalCompletion(unused).
  3. Set the code evaluation state of asyncContext such that when evaluation is resumed for that execution context, closure will be called with no arguments.
  4. Push asyncContext onto the execution context stack; asyncContext is now the running execution context.
  5. Resume the suspended evaluation of asyncContext. Let result be the value returned by the resumed computation.
  6. Assert: When we return here, asyncContext has already been removed from the execution context stack and runningContext is the currently running execution context.
  7. Assert: result is a normal completion with a value of unused. The possible sources of this value are Await or, if the async function doesn't await anything, step 2.i above.
  8. Return unused.

27.7.5.3 Await ( value )

The abstract operation Await takes argument value (an ECMAScript language value) and returns either a normal completion containing either an ECMAScript language value or empty, or a throw completion. It performs the following steps when called:

  1. Let asyncContext be the running execution context.
  2. Let promise be ? PromiseResolve(%Promise%, value).
  3. Let fulfilledClosure be a new Abstract Closure with parameters (v) that captures asyncContext and performs the following steps when called:
    1. Let prevContext be the running execution context.
    2. Suspend prevContext.
    3. Push asyncContext onto the execution context stack; asyncContext is now the running execution context.
    4. Resume the suspended evaluation of asyncContext using NormalCompletion(v) as the result of the operation that suspended it.
    5. Assert: When we reach this step, asyncContext has already been removed from the execution context stack and prevContext is the currently running execution context.
    6. Return NormalCompletion(undefined).
  4. Let onFulfilled be CreateBuiltinFunction(fulfilledClosure, 1, "", « »).
  5. Let rejectedClosure be a new Abstract Closure with parameters (reason) that captures asyncContext and performs the following steps when called:
    1. Let prevContext be the running execution context.
    2. Suspend prevContext.
    3. Push asyncContext onto the execution context stack; asyncContext is now the running execution context.
    4. Resume the suspended evaluation of asyncContext using ThrowCompletion(reason) as the result of the operation that suspended it.
    5. Assert: When we reach this step, asyncContext has already been removed from the execution context stack and prevContext is the currently running execution context.
    6. Return NormalCompletion(undefined).
  6. Let onRejected be CreateBuiltinFunction(rejectedClosure, 1, "", « »).
  7. Perform PerformPromiseThen(promise, onFulfilled, onRejected).
  8. Remove asyncContext from the execution context stack and restore the execution context that is at the top of the execution context stack as the running execution context.
  9. Let callerContext be the running execution context.
  10. Resume callerContext passing empty. If asyncContext is ever resumed again, let completion be the Completion Record with which it is resumed.
  11. Assert: If control reaches here, then asyncContext is the running execution context again.
  12. Return completion.

28 Reflection

28.1 The Reflect Object

The Reflect object:

  • is %Reflect%.
  • is the initial value of the "Reflect" property of the global object.
  • is an ordinary object.
  • has a [[Prototype]] internal slot whose value is %Object.prototype%.
  • is not a function object.
  • does not have a [[Construct]] internal method; it cannot be used as a constructor with the new operator.
  • does not have a [[Call]] internal method; it cannot be invoked as a function.

28.1.1 Reflect.apply ( target, thisArgument, argumentsList )

This function performs the following steps when called:

  1. If IsCallable(target) is false, throw a TypeError exception.
  2. Let args be ? CreateListFromArrayLike(argumentsList).
  3. Perform PrepareForTailCall().
  4. Return ? Call(target, thisArgument, args).

28.1.2 Reflect.construct ( target, argumentsList [ , newTarget ] )

This function performs the following steps when called:

  1. If IsConstructor(target) is false, throw a TypeError exception.
  2. If newTarget is not present, set newTarget to target.
  3. Else if IsConstructor(newTarget) is false, throw a TypeError exception.
  4. Let args be ? CreateListFromArrayLike(argumentsList).
  5. Return ? Construct(target, args, newTarget).

28.1.3 Reflect.defineProperty ( target, propertyKey, attributes )

This function performs the following steps when called:

  1. If target is not an Object, throw a TypeError exception.
  2. Let key be ? ToPropertyKey(propertyKey).
  3. Let desc be ? ToPropertyDescriptor(attributes).
  4. Return ? target.[[DefineOwnProperty]](key, desc).

28.1.4 Reflect.deleteProperty ( target, propertyKey )

This function performs the following steps when called:

  1. If target is not an Object, throw a TypeError exception.
  2. Let key be ? ToPropertyKey(propertyKey).
  3. Return ? target.[[Delete]](key).

28.1.5 Reflect.get ( target, propertyKey [ , receiver ] )

This function performs the following steps when called:

  1. If target is not an Object, throw a TypeError exception.
  2. Let key be ? ToPropertyKey(propertyKey).
  3. If receiver is not present, then
    1. Set receiver to target.
  4. Return ? target.[[Get]](key, receiver).

28.1.6 Reflect.getOwnPropertyDescriptor ( target, propertyKey )

This function performs the following steps when called:

  1. If target is not an Object, throw a TypeError exception.
  2. Let key be ? ToPropertyKey(propertyKey).
  3. Let desc be ? target.[[GetOwnProperty]](key).
  4. Return FromPropertyDescriptor(desc).

28.1.7 Reflect.getPrototypeOf ( target )

This function performs the following steps when called:

  1. If target is not an Object, throw a TypeError exception.
  2. Return ? target.[[GetPrototypeOf]]().

28.1.8 Reflect.has ( target, propertyKey )

This function performs the following steps when called:

  1. If target is not an Object, throw a TypeError exception.
  2. Let key be ? ToPropertyKey(propertyKey).
  3. Return ? target.[[HasProperty]](key).

28.1.9 Reflect.isExtensible ( target )

This function performs the following steps when called:

  1. If target is not an Object, throw a TypeError exception.
  2. Return ? target.[[IsExtensible]]().

28.1.10 Reflect.ownKeys ( target )

This function performs the following steps when called:

  1. If target is not an Object, throw a TypeError exception.
  2. Let keys be ? target.[[OwnPropertyKeys]]().
  3. Return CreateArrayFromList(keys).

28.1.11 Reflect.preventExtensions ( target )

This function performs the following steps when called:

  1. If target is not an Object, throw a TypeError exception.
  2. Return ? target.[[PreventExtensions]]().

28.1.12 Reflect.set ( target, propertyKey, V [ , receiver ] )

This function performs the following steps when called:

  1. If target is not an Object, throw a TypeError exception.
  2. Let key be ? ToPropertyKey(propertyKey).
  3. If receiver is not present, then
    1. Set receiver to target.
  4. Return ? target.[[Set]](key, V, receiver).

28.1.13 Reflect.setPrototypeOf ( target, proto )

This function performs the following steps when called:

  1. If target is not an Object, throw a TypeError exception.
  2. If proto is not an Object and proto is not null, throw a TypeError exception.
  3. Return ? target.[[SetPrototypeOf]](proto).

28.1.14 Reflect [ %Symbol.toStringTag% ]

The initial value of the %Symbol.toStringTag% property is the String value "Reflect".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: true }.

28.2 Proxy Objects

28.2.1 The Proxy Constructor

The Proxy constructor:

  • is %Proxy%.
  • is the initial value of the "Proxy" property of the global object.
  • creates and initializes a new Proxy object when called as a constructor.
  • is not intended to be called as a function and will throw an exception when called in that manner.

28.2.1.1 Proxy ( target, handler )

This function performs the following steps when called:

  1. If NewTarget is undefined, throw a TypeError exception.
  2. Return ? ProxyCreate(target, handler).

28.2.2 Properties of the Proxy Constructor

The Proxy constructor:

  • has a [[Prototype]] internal slot whose value is %Function.prototype%.
  • does not have a "prototype" property because Proxy objects do not have a [[Prototype]] internal slot that requires initialization.
  • has the following properties:

28.2.2.1 Proxy.revocable ( target, handler )

This function creates a revocable Proxy object.

It performs the following steps when called:

  1. Let proxy be ? ProxyCreate(target, handler).
  2. Let revokerClosure be a new Abstract Closure with no parameters that captures nothing and performs the following steps when called:
    1. Let F be the active function object.
    2. Let p be F.[[RevocableProxy]].
    3. If p is null, return NormalCompletion(undefined).
    4. Set F.[[RevocableProxy]] to null.
    5. Assert: p is a Proxy exotic object.
    6. Set p.[[ProxyTarget]] to null.
    7. Set p.[[ProxyHandler]] to null.
    8. Return NormalCompletion(undefined).
  3. Let revoker be CreateBuiltinFunction(revokerClosure, 0, "", « [[RevocableProxy]] »).
  4. Set revoker.[[RevocableProxy]] to proxy.
  5. Let result be OrdinaryObjectCreate(%Object.prototype%).
  6. Perform ! CreateDataPropertyOrThrow(result, "proxy", proxy).
  7. Perform ! CreateDataPropertyOrThrow(result, "revoke", revoker).
  8. Return result.

28.3 Module Namespace Objects

A Module Namespace Object is a module namespace exotic object that provides runtime property-based access to a module's exported bindings. There is no constructor function for Module Namespace Objects. Instead, such an object is created for each module that is imported by an ImportDeclaration that contains a NameSpaceImport.

In addition to the properties specified in 10.4.6 each Module Namespace Object has the following own property:

28.3.1 %Symbol.toStringTag%

The initial value of the %Symbol.toStringTag% property is the String value "Module".

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

29 Memory Model

The memory consistency model, or memory model, specifies the possible orderings of Shared Data Block events, arising via accessing TypedArray instances backed by a SharedArrayBuffer and via methods on the Atomics object. When the program has no data races (defined below), the ordering of events appears as sequentially consistent, i.e., as an interleaving of actions from each agent. When the program has data races, shared memory operations may appear sequentially inconsistent. For example, programs may exhibit causality-violating behaviour and other astonishments. These astonishments arise from compiler transforms and the design of CPUs (e.g., out-of-order execution and speculation). The memory model defines both the precise conditions under which a program exhibits sequentially consistent behaviour as well as the possible values read from data races. To wit, there is no undefined behaviour.

The memory model is defined as relational constraints on events introduced by abstract operations on SharedArrayBuffer or by methods on the Atomics object during an evaluation.

Note

This section provides an axiomatic model on events introduced by the abstract operations on SharedArrayBuffers. It bears stressing that the model is not expressible algorithmically, unlike the rest of this specification. The nondeterministic introduction of events by abstract operations is the interface between the operational semantics of ECMAScript evaluation and the axiomatic semantics of the memory model. The semantics of these events is defined by considering graphs of all events in an evaluation. These are neither Static Semantics nor Runtime Semantics. There is no demonstrated algorithmic implementation, but instead a set of constraints that determine if a particular event graph is allowed or disallowed.

29.1 Memory Model Fundamentals

Shared memory accesses (reads and writes) are divided into two groups, atomic accesses and data accesses, defined below. Atomic accesses are sequentially consistent, i.e., there is a strict total ordering of events agreed upon by all agents in an agent cluster. Non-atomic accesses do not have a strict total ordering agreed upon by all agents, i.e., unordered.

Note 1

No orderings weaker than sequentially consistent and stronger than unordered, such as release-acquire, are supported.

A Shared Data Block event is either a ReadSharedMemory, WriteSharedMemory, or ReadModifyWriteSharedMemory Record.

Table 96: ReadSharedMemory Event Fields
Field Name Value Meaning
[[Order]] seq-cst or unordered The weakest ordering guaranteed by the memory model for the event.
[[NoTear]] a Boolean Whether this event is allowed to read from multiple write events with equal range as this event.
[[Block]] a Shared Data Block The block the event operates on.
[[ByteIndex]] a non-negative integer The byte address of the read in [[Block]].
[[ElementSize]] a non-negative integer The size of the read.
Table 97: WriteSharedMemory Event Fields
Field Name Value Meaning
[[Order]] seq-cst, unordered, or init The weakest ordering guaranteed by the memory model for the event.
[[NoTear]] a Boolean Whether this event is allowed to be read from multiple read events with equal range as this event.
[[Block]] a Shared Data Block The block the event operates on.
[[ByteIndex]] a non-negative integer The byte address of the write in [[Block]].
[[ElementSize]] a non-negative integer The size of the write.
[[Payload]] a List of byte values The List of byte values to be read by other events.
Table 98: ReadModifyWriteSharedMemory Event Fields
Field Name Value Meaning
[[Order]] seq-cst Read-modify-write events are always sequentially consistent.
[[NoTear]] true Read-modify-write events cannot tear.
[[Block]] a Shared Data Block The block the event operates on.
[[ByteIndex]] a non-negative integer The byte address of the read-modify-write in [[Block]].
[[ElementSize]] a non-negative integer The size of the read-modify-write.
[[Payload]] a List of byte values The List of byte values to be passed to [[ModifyOp]].
[[ModifyOp]] a read-modify-write modification function An abstract closure that returns a modified List of byte values from a read List of byte values and [[Payload]].

These events are introduced by abstract operations or by methods on the Atomics object.

Some operations may also introduce Synchronize events. A Synchronize event has no fields, and exists purely to directly constrain the permitted orderings of other events.

In addition to Shared Data Block and Synchronize events, there are host-specific events.

Let the range of a ReadSharedMemory, WriteSharedMemory, or ReadModifyWriteSharedMemory event be the Set of contiguous integers from its [[ByteIndex]] to [[ByteIndex]] + [[ElementSize]] - 1. Two events' ranges are equal when the events have the same [[Block]], and the ranges are element-wise equal. Two events' ranges are overlapping when the events have the same [[Block]], the ranges are not equal and their intersection is non-empty. Two events' ranges are disjoint when the events do not have the same [[Block]] or their ranges are neither equal nor overlapping.

Note 2

Examples of host-specific synchronizing events that should be accounted for are: sending a SharedArrayBuffer from one agent to another (e.g., by postMessage in a browser), starting and stopping agents, and communicating within the agent cluster via channels other than shared memory. For a particular execution execution, those events are provided by the host via the host-synchronizes-with strict partial order. Additionally, hosts can add host-specific synchronizing events to execution.[[EventList]] so as to participate in the is-agent-order-before Relation.

Events are ordered within candidate executions by the relations defined below.

29.2 Agent Events Records

An Agent Events Record is a Record with the following fields.

Table 99: Agent Events Record Fields
Field Name Value Meaning
[[AgentSignifier]] an agent signifier The agent whose evaluation resulted in this ordering.
[[EventList]] a List of events Events are appended to the list during evaluation.
[[AgentSynchronizesWith]] a List of pairs of Synchronize events Synchronize relationships introduced by the operational semantics.

29.3 Chosen Value Records

A Chosen Value Record is a Record with the following fields.

Table 100: Chosen Value Record Fields
Field Name Value Meaning
[[Event]] a Shared Data Block event The ReadSharedMemory or ReadModifyWriteSharedMemory event that was introduced for this chosen value.
[[ChosenValue]] a List of byte values The bytes that were nondeterministically chosen during evaluation.

29.4 Candidate Executions

A candidate execution of the evaluation of an agent cluster is a Record with the following fields.

Table 101: Candidate Execution Record Fields
Field Name Value Meaning
[[EventsRecords]] a List of Agent Events Records Maps an agent to Lists of events appended during the evaluation.
[[ChosenValues]] a List of Chosen Value Records Maps ReadSharedMemory or ReadModifyWriteSharedMemory events to the List of byte values chosen during the evaluation.

An empty candidate execution is a candidate execution Record whose fields are empty Lists.

29.5 Abstract Operations for the Memory Model

29.5.1 EventSet ( execution )

The abstract operation EventSet takes argument execution (a candidate execution) and returns a Set of events. It performs the following steps when called:

  1. Let events be an empty Set.
  2. For each Agent Events Record aer of execution.[[EventsRecords]], do
    1. For each event E of aer.[[EventList]], do
      1. Add E to events.
  3. Return events.

29.5.2 SharedDataBlockEventSet ( execution )

The abstract operation SharedDataBlockEventSet takes argument execution (a candidate execution) and returns a Set of events. It performs the following steps when called:

  1. Let events be an empty Set.
  2. For each event E of EventSet(execution), do
    1. If E is a ReadSharedMemory, WriteSharedMemory, or ReadModifyWriteSharedMemory event, add E to events.
  3. Return events.

29.5.3 HostEventSet ( execution )

The abstract operation HostEventSet takes argument execution (a candidate execution) and returns a Set of events. It performs the following steps when called:

  1. Let events be an empty Set.
  2. For each event E of EventSet(execution), do
    1. If E is not in SharedDataBlockEventSet(execution), add E to events.
  3. Return events.

29.5.4 ComposeWriteEventBytes ( execution, byteIndex, Ws )

The abstract operation ComposeWriteEventBytes takes arguments execution (a candidate execution), byteIndex (a non-negative integer), and Ws (a List of either WriteSharedMemory or ReadModifyWriteSharedMemory events) and returns a List of byte values. It performs the following steps when called:

  1. Let byteLocation be byteIndex.
  2. Let bytesRead be a new empty List.
  3. For each element W of Ws, do
    1. Assert: W has byteLocation in its range.
    2. Let payloadIndex be byteLocation - W.[[ByteIndex]].
    3. If W is a WriteSharedMemory event, then
      1. Let byte be W.[[Payload]][payloadIndex].
    4. Else,
      1. Assert: W is a ReadModifyWriteSharedMemory event.
      2. Let bytes be ValueOfReadEvent(execution, W).
      3. Let bytesModified be W.[[ModifyOp]](bytes, W.[[Payload]]).
      4. Let byte be bytesModified[payloadIndex].
    5. Append byte to bytesRead.
    6. Set byteLocation to byteLocation + 1.
  4. Return bytesRead.
Note 1

The read-modify-write modification [[ModifyOp]] is given by the function properties on the Atomics object that introduce ReadModifyWriteSharedMemory events.

Note 2

This abstract operation composes a List of write events into a List of byte values. It is used in the event semantics of ReadSharedMemory and ReadModifyWriteSharedMemory events.

29.5.5 ValueOfReadEvent ( execution, R )

The abstract operation ValueOfReadEvent takes arguments execution (a candidate execution) and R (a ReadSharedMemory or ReadModifyWriteSharedMemory event) and returns a List of byte values. It performs the following steps when called:

  1. Let Ws be reads-bytes-from(R) in execution.
  2. Assert: Ws is a List of WriteSharedMemory or ReadModifyWriteSharedMemory events with length equal to R.[[ElementSize]].
  3. Return ComposeWriteEventBytes(execution, R.[[ByteIndex]], Ws).

29.6 Relations of Candidate Executions

The following relations and mathematical functions are parameterized over a particular candidate execution and order its events.

29.6.1 is-agent-order-before

For a candidate execution execution, its is-agent-order-before Relation is the least Relation on events that satisfies the following.

  • For events E and D, E is-agent-order-before D in execution if there is some Agent Events Record aer in execution.[[EventsRecords]] such that aer.[[EventList]] contains both E and D and E is before D in List order of aer.[[EventList]].
Note

Each agent introduces events in a per-agent strict total order during the evaluation. This is the union of those strict total orders.

29.6.2 reads-bytes-from

For a candidate execution execution, its reads-bytes-from function is a mathematical function mapping events in SharedDataBlockEventSet(execution) to Lists of events in SharedDataBlockEventSet(execution) that satisfies the following conditions.

A candidate execution always admits a reads-bytes-from function.

29.6.3 reads-from

For a candidate execution execution, its reads-from Relation is the least Relation on events that satisfies the following.

29.6.4 host-synchronizes-with

For a candidate execution execution, its host-synchronizes-with Relation is a host-provided strict partial order on host-specific events that satisfies at least the following.

  • If E host-synchronizes-with D in execution, HostEventSet(execution) contains E and D.
  • There is no cycle in the union of host-synchronizes-with and is-agent-order-before in execution.
Note 1

For two host-specific events E and D in a candidate execution execution, E host-synchronizes-with D in execution implies E happens-before D in execution.

Note 2

This Relation allows the host to provide additional synchronization mechanisms, such as postMessage between HTML workers.

29.6.5 synchronizes-with

For a candidate execution execution, its synchronizes-with Relation is the least Relation on events that satisfies the following.

  • For events R and W, W synchronizes-with R in execution if R reads-from W in execution, R.[[Order]] is seq-cst, W.[[Order]] is seq-cst, and R and W have equal ranges.
  • For each element eventsRecord of execution.[[EventsRecords]], the following is true.
    • For events S and Sw, S synchronizes-with Sw in execution if eventsRecord.[[AgentSynchronizesWith]] contains (S, Sw).
  • For events E and D, E synchronizes-with D in execution if execution.[[HostSynchronizesWith]] contains (E, D).
Note 1

Owing to convention in memory model literature, in a candidate execution execution, write events synchronizes-with read events, instead of read events synchronizes-with write events.

Note 2

In a candidate execution execution, init events do not participate in this Relation and are instead constrained directly by happens-before.

Note 3

In a candidate execution execution, not all seq-cst events related by reads-from are related by synchronizes-with. Only events that also have equal ranges are related by synchronizes-with.

Note 4

For Shared Data Block events R and W in a candidate execution execution such that W synchronizes-with R, R may reads-from other writes than W.

29.6.6 happens-before

For a candidate execution execution, its happens-before Relation is the least Relation on events that satisfies the following.

  • For events E and D, E happens-before D in execution if any of the following conditions are true.

Note

Because happens-before is a superset of agent-order, a candidate execution is consistent with the single-thread evaluation semantics of ECMAScript.

29.7 Properties of Valid Executions

29.7.1 Valid Chosen Reads

A candidate execution execution has valid chosen reads if the following algorithm returns true.

  1. For each ReadSharedMemory or ReadModifyWriteSharedMemory event R of SharedDataBlockEventSet(execution), do
    1. Let chosenValueRecord be the element of execution.[[ChosenValues]] whose [[Event]] field is R.
    2. Let chosenValue be chosenValueRecord.[[ChosenValue]].
    3. Let readValue be ValueOfReadEvent(execution, R).
    4. Let chosenLen be the number of elements in chosenValue.
    5. Let readLen be the number of elements in readValue.
    6. If chosenLenreadLen, then
      1. Return false.
    7. If chosenValue[i] ≠ readValue[i] for some integer i in the interval from 0 (inclusive) to chosenLen (exclusive), then
      1. Return false.
  2. Return true.

29.7.2 Coherent Reads

A candidate execution execution has coherent reads if the following algorithm returns true.

  1. For each ReadSharedMemory or ReadModifyWriteSharedMemory event R of SharedDataBlockEventSet(execution), do
    1. Let Ws be reads-bytes-from(R) in execution.
    2. Let byteLocation be R.[[ByteIndex]].
    3. For each element W of Ws, do
      1. If R happens-before W in execution, then
        1. Return false.
      2. If there exists a WriteSharedMemory or ReadModifyWriteSharedMemory event V that has byteLocation in its range such that W happens-before V in execution and V happens-before R in execution, then
        1. Return false.
      3. Set byteLocation to byteLocation + 1.
  2. Return true.

29.7.3 Tear Free Reads

A candidate execution execution has tear free reads if the following algorithm returns true.

  1. For each ReadSharedMemory or ReadModifyWriteSharedMemory event R of SharedDataBlockEventSet(execution), do
    1. If R.[[NoTear]] is true, then
      1. Assert: The remainder of dividing R.[[ByteIndex]] by R.[[ElementSize]] is 0.
      2. For each event W such that R reads-from W in execution and W.[[NoTear]] is true, do
        1. If R and W have equal ranges and there exists an event V such that V and W have equal ranges, V.[[NoTear]] is true, W and V are not the same Shared Data Block event, and R reads-from V in execution, then
          1. Return false.
  2. Return true.
Note

An event's [[NoTear]] field is true when that event was introduced via accessing an integer TypedArray, and false when introduced via accessing a floating point TypedArray or DataView.

Intuitively, this requirement says when a memory range is accessed in an aligned fashion via an integer TypedArray, a single write event on that range must "win" when in a data race with other write events with equal ranges. More precisely, this requirement says an aligned read event cannot read a value composed of bytes from multiple, different write events all with equal ranges. It is possible, however, for an aligned read event to read from multiple write events with overlapping ranges.

29.7.4 Sequentially Consistent Atomics

For a candidate execution execution, is-memory-order-before is a strict total order of all events in EventSet(execution) that satisfies the following.

A candidate execution has sequentially consistent atomics if it admits an is-memory-order-before Relation.

Note 3

While is-memory-order-before includes all events in EventSet(execution), those that are not constrained by happens-before or synchronizes-with in execution are allowed to occur anywhere in the order.

29.7.5 Valid Executions

A candidate execution execution is a valid execution (or simply an execution) if all of the following are true.

All programs have at least one valid execution.

29.8 Races

For an execution execution and events E and D that are contained in SharedDataBlockEventSet(execution), E and D are in a race if the following algorithm returns true.

  1. If E and D are not the same Shared Data Block event, then
    1. If it is not the case that both E happens-before D in execution and D happens-before E in execution, then
      1. If E and D are both WriteSharedMemory or ReadModifyWriteSharedMemory events and E and D do not have disjoint ranges, then
        1. Return true.
      2. If E reads-from D in execution or D reads-from E in execution, then
        1. Return true.
  2. Return false.

29.9 Data Races

For an execution execution and events E and D that are contained in SharedDataBlockEventSet(execution), E and D are in a data race if the following algorithm returns true.

  1. If E and D are in a race in execution, then
    1. If E.[[Order]] is not seq-cst or D.[[Order]] is not seq-cst, then
      1. Return true.
    2. If E and D have overlapping ranges, then
      1. Return true.
  2. Return false.

29.10 Data Race Freedom

An execution execution is data race free if there are no two events in SharedDataBlockEventSet(execution) that are in a data race.

A program is data race free if all its executions are data race free.

The memory model guarantees sequential consistency of all events for data race free programs.

29.11 Shared Memory Guidelines

Note 1

The following are guidelines for ECMAScript programmers working with shared memory.

We recommend programs be kept data race free, i.e., make it so that it is impossible for there to be concurrent non-atomic operations on the same memory location. Data race free programs have interleaving semantics where each step in the evaluation semantics of each agent are interleaved with each other. For data race free programs, it is not necessary to understand the details of the memory model. The details are unlikely to build intuition that will help one to better write ECMAScript.

More generally, even if a program is not data race free it may have predictable behaviour, so long as atomic operations are not involved in any data races and the operations that race all have the same access size. The simplest way to arrange for atomics not to be involved in races is to ensure that different memory cells are used by atomic and non-atomic operations and that atomic accesses of different sizes are not used to access the same cells at the same time. Effectively, the program should treat shared memory as strongly typed as much as possible. One still cannot depend on the ordering and timing of non-atomic accesses that race, but if memory is treated as strongly typed the racing accesses will not "tear" (bits of their values will not be mixed).

Note 2

The following are guidelines for ECMAScript implementers writing compiler transformations for programs using shared memory.

It is desirable to allow most program transformations that are valid in a single-agent setting in a multi-agent setting, to ensure that the performance of each agent in a multi-agent program is as good as it would be in a single-agent setting. Frequently these transformations are hard to judge. We outline some rules about program transformations that are intended to be taken as normative (in that they are implied by the memory model or stronger than what the memory model implies) but which are likely not exhaustive. These rules are intended to apply to program transformations that precede the introductions of the events that make up the is-agent-order-before Relation.

Let an agent-order slice be the subset of the is-agent-order-before Relation pertaining to a single agent.

Let possible read values of a read event be the set of all values of ValueOfReadEvent for that event across all valid executions.

Any transformation of an agent-order slice that is valid in the absence of shared memory is valid in the presence of shared memory, with the following exceptions.

  • Atomics are carved in stone: Program transformations must not cause the seq-cst events in an agent-order slice to be reordered with its unordered operations, nor its seq-cst operations to be reordered with each other, nor may a program transformation remove a seq-cst operation from the is-agent-order-before Relation.

    (In practice, the prohibition on reorderings forces a compiler to assume that every seq-cst operation is a synchronization and included in the final is-memory-order-before Relation, which it would usually have to assume anyway in the absence of inter-agent program analysis. It also forces the compiler to assume that every call where the callee's effects on the memory-order are unknown may contain seq-cst operations.)

  • Reads must be stable: Any given shared memory read must only observe a single value in an execution.

    (For example, if what is semantically a single read in the program is executed multiple times then the program is subsequently allowed to observe only one of the values read. A transformation known as rematerialization can violate this rule.)

  • Writes must be stable: All observable writes to shared memory must follow from program semantics in an execution.

    (For example, a transformation may not introduce certain observable writes, such as by using read-modify-write operations on a larger location to write a smaller datum, writing a value to memory that the program could not have written, or writing a just-read value back to the location it was read from, if that location could have been overwritten by another agent after the read.)

  • Possible read values must be non-empty: Program transformations cannot cause the possible read values of a shared memory read to become empty.

    (Counterintuitively, this rule in effect restricts transformations on writes, because writes have force in memory model insofar as to be read by read events. For example, writes may be moved and coalesced and sometimes reordered between two seq-cst operations, but the transformation may not remove every write that updates a location; some write must be preserved.)

Examples of transformations that remain valid are: merging multiple non-atomic reads from the same location, reordering non-atomic reads, introducing speculative non-atomic reads, merging multiple non-atomic writes to the same location, reordering non-atomic writes to different locations, and hoisting non-atomic reads out of loops even if that affects termination. Note in general that aliased TypedArrays make it hard to prove that locations are different.

Note 3

The following are guidelines for ECMAScript implementers generating machine code for shared memory accesses.

For architectures with memory models no weaker than those of ARM or Power, non-atomic stores and loads may be compiled to bare stores and loads on the target architecture. Atomic stores and loads may be compiled down to instructions that guarantee sequential consistency. If no such instructions exist, memory barriers are to be employed, such as placing barriers on both sides of a bare store or load. Read-modify-write operations may be compiled to read-modify-write instructions on the target architecture, such as LOCK-prefixed instructions on x86, load-exclusive/store-exclusive instructions on ARM, and load-link/store-conditional instructions on Power.

Specifically, the memory model is intended to allow code generation as follows.

  • Every atomic operation in the program is assumed to be necessary.
  • Atomic operations are never rearranged with each other or with non-atomic operations.
  • Functions are always assumed to perform atomic operations.
  • Atomic operations are never implemented as read-modify-write operations on larger data, but as non-lock-free atomics if the platform does not have atomic operations of the appropriate size. (We already assume that every platform has normal memory access operations of every interesting size.)

Naive code generation uses these patterns:

  • Regular loads and stores compile to single load and store instructions.
  • Lock-free atomic loads and stores compile to a full (sequentially consistent) fence, a regular load or store, and a full fence.
  • Lock-free atomic read-modify-write accesses compile to a full fence, an atomic read-modify-write instruction sequence, and a full fence.
  • Non-lock-free atomics compile to a spinlock acquire, a full fence, a series of non-atomic load and store instructions, a full fence, and a spinlock release.

That mapping is correct so long as an atomic operation on an address range does not race with a non-atomic write or with an atomic operation of different size. However, that is all we need: the memory model effectively demotes the atomic operations involved in a race to non-atomic status. On the other hand, the naive mapping is quite strong: it allows atomic operations to be used as sequentially consistent fences, which the memory model does not actually guarantee.

Local improvements to those basic patterns are also allowed, subject to the constraints of the memory model. For example:

  • There are obvious platform-dependent improvements that remove redundant fences. For example, on x86 the fences around lock-free atomic loads and stores can always be omitted except for the fence following a store, and no fence is needed for lock-free read-modify-write instructions, as these all use LOCK-prefixed instructions. On many platforms there are fences of several strengths, and weaker fences can be used in certain contexts without destroying sequential consistency.
  • Most modern platforms support lock-free atomics for all the data sizes required by ECMAScript atomics. Should non-lock-free atomics be needed, the fences surrounding the body of the atomic operation can usually be folded into the lock and unlock steps. The simplest solution for non-lock-free atomics is to have a single lock word per SharedArrayBuffer.
  • There are also more complicated platform-dependent local improvements, requiring some code analysis. For example, two back-to-back fences often have the same effect as a single fence, so if code is generated for two atomic operations in sequence, only a single fence need separate them. On x86, even a single fence separating atomic stores can be omitted, as the fence following a store is only needed to separate the store from a subsequent load.

Annex A (informative) Grammar Summary

A.1 Lexical Grammar

SourceCharacter :: any Unicode code point InputElementDiv :: WhiteSpace LineTerminator Comment CommonToken DivPunctuator RightBracePunctuator InputElementRegExp :: WhiteSpace LineTerminator Comment CommonToken RightBracePunctuator RegularExpressionLiteral InputElementRegExpOrTemplateTail :: WhiteSpace LineTerminator Comment CommonToken RegularExpressionLiteral TemplateSubstitutionTail InputElementTemplateTail :: WhiteSpace LineTerminator Comment CommonToken DivPunctuator TemplateSubstitutionTail InputElementHashbangOrRegExp :: WhiteSpace LineTerminator Comment CommonToken HashbangComment RegularExpressionLiteral WhiteSpace :: <TAB> <VT> <FF> <ZWNBSP> <USP> LineTerminator :: <LF> <CR> <LS> <PS> LineTerminatorSequence :: <LF> <CR> [lookahead ≠ <LF>] <LS> <PS> <CR> <LF> Comment :: MultiLineComment SingleLineComment MultiLineComment :: /* MultiLineCommentCharsopt */ MultiLineCommentChars :: MultiLineNotAsteriskChar MultiLineCommentCharsopt * PostAsteriskCommentCharsopt PostAsteriskCommentChars :: MultiLineNotForwardSlashOrAsteriskChar MultiLineCommentCharsopt * PostAsteriskCommentCharsopt MultiLineNotAsteriskChar :: SourceCharacter but not * MultiLineNotForwardSlashOrAsteriskChar :: SourceCharacter but not one of / or * SingleLineComment :: // SingleLineCommentCharsopt SingleLineCommentChars :: SingleLineCommentChar SingleLineCommentCharsopt SingleLineCommentChar :: SourceCharacter but not LineTerminator HashbangComment :: #! SingleLineCommentCharsopt CommonToken :: IdentifierName PrivateIdentifier Punctuator NumericLiteral StringLiteral Template PrivateIdentifier :: # IdentifierName IdentifierName :: IdentifierStart IdentifierName IdentifierPart IdentifierStart :: IdentifierStartChar \ UnicodeEscapeSequence IdentifierPart :: IdentifierPartChar \ UnicodeEscapeSequence IdentifierStartChar :: UnicodeIDStart $ _ IdentifierPartChar :: UnicodeIDContinue $ AsciiLetter :: one of a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z UnicodeIDStart :: any Unicode code point with the Unicode property “ID_Start” UnicodeIDContinue :: any Unicode code point with the Unicode property “ID_Continue” ReservedWord :: one of await break case catch class const continue debugger default delete do else enum export extends false finally for function if import in instanceof new null return super switch this throw true try typeof var void while with yield Punctuator :: OptionalChainingPunctuator OtherPunctuator OptionalChainingPunctuator :: ?. [lookahead ∉ DecimalDigit] OtherPunctuator :: one of { ( ) [ ] . ... ; , < > <= >= == != === !== + - * % ** ++ -- << >> >>> & | ^ ! ~ && || ?? ? : = += -= *= %= **= <<= >>= >>>= &= |= ^= &&= ||= ??= => DivPunctuator :: / /= RightBracePunctuator :: } NullLiteral :: null BooleanLiteral :: true false NumericLiteralSeparator :: _ NumericLiteral :: DecimalLiteral DecimalBigIntegerLiteral NonDecimalIntegerLiteral[+Sep] NonDecimalIntegerLiteral[+Sep] BigIntLiteralSuffix LegacyOctalIntegerLiteral DecimalBigIntegerLiteral :: 0 BigIntLiteralSuffix NonZeroDigit DecimalDigits[+Sep]opt BigIntLiteralSuffix NonZeroDigit NumericLiteralSeparator DecimalDigits[+Sep] BigIntLiteralSuffix NonDecimalIntegerLiteral[Sep] :: BinaryIntegerLiteral[?Sep] OctalIntegerLiteral[?Sep] HexIntegerLiteral[?Sep] BigIntLiteralSuffix :: n DecimalLiteral :: DecimalIntegerLiteral . DecimalDigits[+Sep]opt ExponentPart[+Sep]opt . DecimalDigits[+Sep] ExponentPart[+Sep]opt DecimalIntegerLiteral ExponentPart[+Sep]opt DecimalIntegerLiteral :: 0 NonZeroDigit NonZeroDigit NumericLiteralSeparatoropt DecimalDigits[+Sep] NonOctalDecimalIntegerLiteral DecimalDigits[Sep] :: DecimalDigit DecimalDigits[?Sep] DecimalDigit [+Sep] DecimalDigits[+Sep] NumericLiteralSeparator DecimalDigit DecimalDigit :: one of 0 1 2 3 4 5 6 7 8 9 NonZeroDigit :: one of 1 2 3 4 5 6 7 8 9 ExponentPart[Sep] :: ExponentIndicator SignedInteger[?Sep] ExponentIndicator :: one of e E SignedInteger[Sep] :: DecimalDigits[?Sep] + DecimalDigits[?Sep] - DecimalDigits[?Sep] BinaryIntegerLiteral[Sep] :: 0b BinaryDigits[?Sep] 0B BinaryDigits[?Sep] BinaryDigits[Sep] :: BinaryDigit BinaryDigits[?Sep] BinaryDigit [+Sep] BinaryDigits[+Sep] NumericLiteralSeparator BinaryDigit BinaryDigit :: one of 0 1 OctalIntegerLiteral[Sep] :: 0o OctalDigits[?Sep] 0O OctalDigits[?Sep] OctalDigits[Sep] :: OctalDigit OctalDigits[?Sep] OctalDigit [+Sep] OctalDigits[+Sep] NumericLiteralSeparator OctalDigit LegacyOctalIntegerLiteral :: 0 OctalDigit LegacyOctalIntegerLiteral OctalDigit NonOctalDecimalIntegerLiteral :: 0 NonOctalDigit LegacyOctalLikeDecimalIntegerLiteral NonOctalDigit NonOctalDecimalIntegerLiteral DecimalDigit LegacyOctalLikeDecimalIntegerLiteral :: 0 OctalDigit LegacyOctalLikeDecimalIntegerLiteral OctalDigit OctalDigit :: one of 0 1 2 3 4 5 6 7 NonOctalDigit :: one of 8 9 HexIntegerLiteral[Sep] :: 0x HexDigits[?Sep] 0X HexDigits[?Sep] HexDigits[Sep] :: HexDigit HexDigits[?Sep] HexDigit [+Sep] HexDigits[+Sep] NumericLiteralSeparator HexDigit HexDigit :: one of 0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F StringLiteral :: " DoubleStringCharactersopt " ' SingleStringCharactersopt ' DoubleStringCharacters :: DoubleStringCharacter DoubleStringCharactersopt SingleStringCharacters :: SingleStringCharacter SingleStringCharactersopt DoubleStringCharacter :: SourceCharacter but not one of " or \ or LineTerminator <LS> <PS> \ EscapeSequence LineContinuation SingleStringCharacter :: SourceCharacter but not one of ' or \ or LineTerminator <LS> <PS> \ EscapeSequence LineContinuation LineContinuation :: \ LineTerminatorSequence EscapeSequence :: CharacterEscapeSequence 0 [lookahead ∉ DecimalDigit] LegacyOctalEscapeSequence NonOctalDecimalEscapeSequence HexEscapeSequence UnicodeEscapeSequence CharacterEscapeSequence :: SingleEscapeCharacter NonEscapeCharacter SingleEscapeCharacter :: one of ' " \ b f n r t v NonEscapeCharacter :: SourceCharacter but not one of EscapeCharacter or LineTerminator EscapeCharacter :: SingleEscapeCharacter DecimalDigit x u LegacyOctalEscapeSequence :: 0 [lookahead ∈ { 8, 9 }] NonZeroOctalDigit [lookahead ∉ OctalDigit] ZeroToThree OctalDigit [lookahead ∉ OctalDigit] FourToSeven OctalDigit ZeroToThree OctalDigit OctalDigit NonZeroOctalDigit :: OctalDigit but not 0 ZeroToThree :: one of 0 1 2 3 FourToSeven :: one of 4 5 6 7 NonOctalDecimalEscapeSequence :: one of 8 9 HexEscapeSequence :: x HexDigit HexDigit UnicodeEscapeSequence :: u Hex4Digits u{ CodePoint } Hex4Digits :: HexDigit HexDigit HexDigit HexDigit RegularExpressionLiteral :: / RegularExpressionBody / RegularExpressionFlags RegularExpressionBody :: RegularExpressionFirstChar RegularExpressionChars RegularExpressionChars :: [empty] RegularExpressionChars RegularExpressionChar RegularExpressionFirstChar :: RegularExpressionNonTerminator but not one of * or \ or / or [ RegularExpressionBackslashSequence RegularExpressionClass RegularExpressionChar :: RegularExpressionNonTerminator but not one of \ or / or [ RegularExpressionBackslashSequence RegularExpressionClass RegularExpressionBackslashSequence :: \ RegularExpressionNonTerminator RegularExpressionNonTerminator :: SourceCharacter but not LineTerminator RegularExpressionClass :: [ RegularExpressionClassChars ] RegularExpressionClassChars :: [empty] RegularExpressionClassChars RegularExpressionClassChar RegularExpressionClassChar :: RegularExpressionNonTerminator but not one of ] or \ RegularExpressionBackslashSequence RegularExpressionFlags :: [empty] RegularExpressionFlags IdentifierPartChar Template :: NoSubstitutionTemplate TemplateHead NoSubstitutionTemplate :: ` TemplateCharactersopt ` TemplateHead :: ` TemplateCharactersopt ${ TemplateSubstitutionTail :: TemplateMiddle TemplateTail TemplateMiddle :: } TemplateCharactersopt ${ TemplateTail :: } TemplateCharactersopt ` TemplateCharacters :: TemplateCharacter TemplateCharactersopt TemplateCharacter :: $ [lookahead ≠ {] \ TemplateEscapeSequence \ NotEscapeSequence LineContinuation LineTerminatorSequence SourceCharacter but not one of ` or \ or $ or LineTerminator TemplateEscapeSequence :: CharacterEscapeSequence 0 [lookahead ∉ DecimalDigit] HexEscapeSequence UnicodeEscapeSequence NotEscapeSequence :: 0 DecimalDigit DecimalDigit but not 0 x [lookahead ∉ HexDigit] x HexDigit [lookahead ∉ HexDigit] u [lookahead ∉ HexDigit] [lookahead ≠ {] u HexDigit [lookahead ∉ HexDigit] u HexDigit HexDigit [lookahead ∉ HexDigit] u HexDigit HexDigit HexDigit [lookahead ∉ HexDigit] u { [lookahead ∉ HexDigit] u { NotCodePoint [lookahead ∉ HexDigit] u { CodePoint [lookahead ∉ HexDigit] [lookahead ≠ }] NotCodePoint :: HexDigits[~Sep] but only if the MV of HexDigits > 0x10FFFF CodePoint :: HexDigits[~Sep] but only if the MV of HexDigits ≤ 0x10FFFF

A.2 Expressions

IdentifierReference[Yield, Await] : Identifier [~Yield] yield [~Await] await BindingIdentifier[Yield, Await] : Identifier yield await LabelIdentifier[Yield, Await] : Identifier [~Yield] yield [~Await] await Identifier : IdentifierName but not ReservedWord PrimaryExpression[Yield, Await] : this IdentifierReference[?Yield, ?Await] Literal ArrayLiteral[?Yield, ?Await] ObjectLiteral[?Yield, ?Await] FunctionExpression ClassExpression[?Yield, ?Await] GeneratorExpression AsyncFunctionExpression AsyncGeneratorExpression RegularExpressionLiteral TemplateLiteral[?Yield, ?Await, ~Tagged] CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await] CoverParenthesizedExpressionAndArrowParameterList[Yield, Await] : ( Expression[+In, ?Yield, ?Await] ) ( Expression[+In, ?Yield, ?Await] , ) ( ) ( ... BindingIdentifier[?Yield, ?Await] ) ( ... BindingPattern[?Yield, ?Await] ) ( Expression[+In, ?Yield, ?Await] , ... BindingIdentifier[?Yield, ?Await] ) ( Expression[+In, ?Yield, ?Await] , ... BindingPattern[?Yield, ?Await] )

When processing an instance of the production
PrimaryExpression[Yield, Await] : CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await]
the interpretation of CoverParenthesizedExpressionAndArrowParameterList is refined using the following grammar:

ParenthesizedExpression[Yield, Await] : ( Expression[+In, ?Yield, ?Await] )

 

Literal : NullLiteral BooleanLiteral NumericLiteral StringLiteral ArrayLiteral[Yield, Await] : [ Elisionopt ] [ ElementList[?Yield, ?Await] ] [ ElementList[?Yield, ?Await] , Elisionopt ] ElementList[Yield, Await] : Elisionopt AssignmentExpression[+In, ?Yield, ?Await] Elisionopt SpreadElement[?Yield, ?Await] ElementList[?Yield, ?Await] , Elisionopt AssignmentExpression[+In, ?Yield, ?Await] ElementList[?Yield, ?Await] , Elisionopt SpreadElement[?Yield, ?Await] Elision : , Elision , SpreadElement[Yield, Await] : ... AssignmentExpression[+In, ?Yield, ?Await] ObjectLiteral[Yield, Await] : { } { PropertyDefinitionList[?Yield, ?Await] } { PropertyDefinitionList[?Yield, ?Await] , } PropertyDefinitionList[Yield, Await] : PropertyDefinition[?Yield, ?Await] PropertyDefinitionList[?Yield, ?Await] , PropertyDefinition[?Yield, ?Await] PropertyDefinition[Yield, Await] : IdentifierReference[?Yield, ?Await] CoverInitializedName[?Yield, ?Await] PropertyName[?Yield, ?Await] : AssignmentExpression[+In, ?Yield, ?Await] MethodDefinition[?Yield, ?Await] ... AssignmentExpression[+In, ?Yield, ?Await] PropertyName[Yield, Await] : LiteralPropertyName ComputedPropertyName[?Yield, ?Await] LiteralPropertyName : IdentifierName StringLiteral NumericLiteral ComputedPropertyName[Yield, Await] : [ AssignmentExpression[+In, ?Yield, ?Await] ] CoverInitializedName[Yield, Await] : IdentifierReference[?Yield, ?Await] Initializer[+In, ?Yield, ?Await] Initializer[In, Yield, Await] : = AssignmentExpression[?In, ?Yield, ?Await] TemplateLiteral[Yield, Await, Tagged] : NoSubstitutionTemplate SubstitutionTemplate[?Yield, ?Await, ?Tagged] SubstitutionTemplate[Yield, Await, Tagged] : TemplateHead Expression[+In, ?Yield, ?Await] TemplateSpans[?Yield, ?Await, ?Tagged] TemplateSpans[Yield, Await, Tagged] : TemplateTail TemplateMiddleList[?Yield, ?Await, ?Tagged] TemplateTail TemplateMiddleList[Yield, Await, Tagged] : TemplateMiddle Expression[+In, ?Yield, ?Await] TemplateMiddleList[?Yield, ?Await, ?Tagged] TemplateMiddle Expression[+In, ?Yield, ?Await] MemberExpression[Yield, Await] : PrimaryExpression[?Yield, ?Await] MemberExpression[?Yield, ?Await] [ Expression[+In, ?Yield, ?Await] ] MemberExpression[?Yield, ?Await] . IdentifierName MemberExpression[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged] SuperProperty[?Yield, ?Await] MetaProperty new MemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await] MemberExpression[?Yield, ?Await] . PrivateIdentifier SuperProperty[Yield, Await] : super [ Expression[+In, ?Yield, ?Await] ] super . IdentifierName MetaProperty : NewTarget ImportMeta NewTarget : new . target ImportMeta : import . meta NewExpression[Yield, Await] : MemberExpression[?Yield, ?Await] new NewExpression[?Yield, ?Await] CallExpression[Yield, Await] : CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await] SuperCall[?Yield, ?Await] ImportCall[?Yield, ?Await] CallExpression[?Yield, ?Await] Arguments[?Yield, ?Await] CallExpression[?Yield, ?Await] [ Expression[+In, ?Yield, ?Await] ] CallExpression[?Yield, ?Await] . IdentifierName CallExpression[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged] CallExpression[?Yield, ?Await] . PrivateIdentifier

When processing an instance of the production
CallExpression[Yield, Await] : CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await]
the interpretation of CoverCallExpressionAndAsyncArrowHead is refined using the following grammar:

CallMemberExpression[Yield, Await] : MemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await]

 

SuperCall[Yield, Await] : super Arguments[?Yield, ?Await] ImportCall[Yield, Await] : import ( AssignmentExpression[+In, ?Yield, ?Await] ,opt ) import ( AssignmentExpression[+In, ?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ,opt ) Arguments[Yield, Await] : ( ) ( ArgumentList[?Yield, ?Await] ) ( ArgumentList[?Yield, ?Await] , ) ArgumentList[Yield, Await] : AssignmentExpression[+In, ?Yield, ?Await] ... AssignmentExpression[+In, ?Yield, ?Await] ArgumentList[?Yield, ?Await] , AssignmentExpression[+In, ?Yield, ?Await] ArgumentList[?Yield, ?Await] , ... AssignmentExpression[+In, ?Yield, ?Await] OptionalExpression[Yield, Await] : MemberExpression[?Yield, ?Await] OptionalChain[?Yield, ?Await] CallExpression[?Yield, ?Await] OptionalChain[?Yield, ?Await] OptionalExpression[?Yield, ?Await] OptionalChain[?Yield, ?Await] OptionalChain[Yield, Await] : ?. Arguments[?Yield, ?Await] ?. [ Expression[+In, ?Yield, ?Await] ] ?. IdentifierName ?. TemplateLiteral[?Yield, ?Await, +Tagged] ?. PrivateIdentifier OptionalChain[?Yield, ?Await] Arguments[?Yield, ?Await] OptionalChain[?Yield, ?Await] [ Expression[+In, ?Yield, ?Await] ] OptionalChain[?Yield, ?Await] . IdentifierName OptionalChain[?Yield, ?Await] TemplateLiteral[?Yield, ?Await, +Tagged] OptionalChain[?Yield, ?Await] . PrivateIdentifier LeftHandSideExpression[Yield, Await] : NewExpression[?Yield, ?Await] CallExpression[?Yield, ?Await] OptionalExpression[?Yield, ?Await] UpdateExpression[Yield, Await] : LeftHandSideExpression[?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await] [no LineTerminator here] ++ LeftHandSideExpression[?Yield, ?Await] [no LineTerminator here] -- ++ UnaryExpression[?Yield, ?Await] -- UnaryExpression[?Yield, ?Await] UnaryExpression[Yield, Await] : UpdateExpression[?Yield, ?Await] delete UnaryExpression[?Yield, ?Await] void UnaryExpression[?Yield, ?Await] typeof UnaryExpression[?Yield, ?Await] + UnaryExpression[?Yield, ?Await] - UnaryExpression[?Yield, ?Await] ~ UnaryExpression[?Yield, ?Await] ! UnaryExpression[?Yield, ?Await] [+Await] AwaitExpression[?Yield] ExponentiationExpression[Yield, Await] : UnaryExpression[?Yield, ?Await] UpdateExpression[?Yield, ?Await] ** ExponentiationExpression[?Yield, ?Await] MultiplicativeExpression[Yield, Await] : ExponentiationExpression[?Yield, ?Await] MultiplicativeExpression[?Yield, ?Await] MultiplicativeOperator ExponentiationExpression[?Yield, ?Await] MultiplicativeOperator : one of * / % AdditiveExpression[Yield, Await] : MultiplicativeExpression[?Yield, ?Await] AdditiveExpression[?Yield, ?Await] + MultiplicativeExpression[?Yield, ?Await] AdditiveExpression[?Yield, ?Await] - MultiplicativeExpression[?Yield, ?Await] ShiftExpression[Yield, Await] : AdditiveExpression[?Yield, ?Await] ShiftExpression[?Yield, ?Await] << AdditiveExpression[?Yield, ?Await] ShiftExpression[?Yield, ?Await] >> AdditiveExpression[?Yield, ?Await] ShiftExpression[?Yield, ?Await] >>> AdditiveExpression[?Yield, ?Await] RelationalExpression[In, Yield, Await] : ShiftExpression[?Yield, ?Await] RelationalExpression[?In, ?Yield, ?Await] < ShiftExpression[?Yield, ?Await] RelationalExpression[?In, ?Yield, ?Await] > ShiftExpression[?Yield, ?Await] RelationalExpression[?In, ?Yield, ?Await] <= ShiftExpression[?Yield, ?Await] RelationalExpression[?In, ?Yield, ?Await] >= ShiftExpression[?Yield, ?Await] RelationalExpression[?In, ?Yield, ?Await] instanceof ShiftExpression[?Yield, ?Await] [+In] RelationalExpression[+In, ?Yield, ?Await] in ShiftExpression[?Yield, ?Await] [+In] PrivateIdentifier in ShiftExpression[?Yield, ?Await] EqualityExpression[In, Yield, Await] : RelationalExpression[?In, ?Yield, ?Await] EqualityExpression[?In, ?Yield, ?Await] == RelationalExpression[?In, ?Yield, ?Await] EqualityExpression[?In, ?Yield, ?Await] != RelationalExpression[?In, ?Yield, ?Await] EqualityExpression[?In, ?Yield, ?Await] === RelationalExpression[?In, ?Yield, ?Await] EqualityExpression[?In, ?Yield, ?Await] !== RelationalExpression[?In, ?Yield, ?Await] BitwiseANDExpression[In, Yield, Await] : EqualityExpression[?In, ?Yield, ?Await] BitwiseANDExpression[?In, ?Yield, ?Await] & EqualityExpression[?In, ?Yield, ?Await] BitwiseXORExpression[In, Yield, Await] : BitwiseANDExpression[?In, ?Yield, ?Await] BitwiseXORExpression[?In, ?Yield, ?Await] ^ BitwiseANDExpression[?In, ?Yield, ?Await] BitwiseORExpression[In, Yield, Await] : BitwiseXORExpression[?In, ?Yield, ?Await] BitwiseORExpression[?In, ?Yield, ?Await] | BitwiseXORExpression[?In, ?Yield, ?Await] LogicalANDExpression[In, Yield, Await] : BitwiseORExpression[?In, ?Yield, ?Await] LogicalANDExpression[?In, ?Yield, ?Await] && BitwiseORExpression[?In, ?Yield, ?Await] LogicalORExpression[In, Yield, Await] : LogicalANDExpression[?In, ?Yield, ?Await] LogicalORExpression[?In, ?Yield, ?Await] || LogicalANDExpression[?In, ?Yield, ?Await] CoalesceExpression[In, Yield, Await] : CoalesceExpressionHead[?In, ?Yield, ?Await] ?? BitwiseORExpression[?In, ?Yield, ?Await] CoalesceExpressionHead[In, Yield, Await] : CoalesceExpression[?In, ?Yield, ?Await] BitwiseORExpression[?In, ?Yield, ?Await] ShortCircuitExpression[In, Yield, Await] : LogicalORExpression[?In, ?Yield, ?Await] CoalesceExpression[?In, ?Yield, ?Await] ConditionalExpression[In, Yield, Await] : ShortCircuitExpression[?In, ?Yield, ?Await] ShortCircuitExpression[?In, ?Yield, ?Await] ? AssignmentExpression[+In, ?Yield, ?Await] : AssignmentExpression[?In, ?Yield, ?Await] AssignmentExpression[In, Yield, Await] : ConditionalExpression[?In, ?Yield, ?Await] [+Yield] YieldExpression[?In, ?Await] ArrowFunction[?In, ?Yield, ?Await] AsyncArrowFunction[?In, ?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await] = AssignmentExpression[?In, ?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await] AssignmentOperator AssignmentExpression[?In, ?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await] &&= AssignmentExpression[?In, ?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await] ||= AssignmentExpression[?In, ?Yield, ?Await] LeftHandSideExpression[?Yield, ?Await] ??= AssignmentExpression[?In, ?Yield, ?Await] AssignmentOperator : one of *= /= %= += -= <<= >>= >>>= &= ^= |= **=

In certain circumstances when processing an instance of the production
AssignmentExpression[In, Yield, Await] : LeftHandSideExpression[?Yield, ?Await] = AssignmentExpression[?In, ?Yield, ?Await]
the interpretation of LeftHandSideExpression is refined using the following grammar:

AssignmentPattern[Yield, Await] : ObjectAssignmentPattern[?Yield, ?Await] ArrayAssignmentPattern[?Yield, ?Await] ObjectAssignmentPattern[Yield, Await] : { } { AssignmentRestProperty[?Yield, ?Await] } { AssignmentPropertyList[?Yield, ?Await] } { AssignmentPropertyList[?Yield, ?Await] , AssignmentRestProperty[?Yield, ?Await]opt } ArrayAssignmentPattern[Yield, Await] : [ Elisionopt AssignmentRestElement[?Yield, ?Await]opt ] [ AssignmentElementList[?Yield, ?Await] ] [ AssignmentElementList[?Yield, ?Await] , Elisionopt AssignmentRestElement[?Yield, ?Await]opt ] AssignmentRestProperty[Yield, Await] : ... DestructuringAssignmentTarget[?Yield, ?Await] AssignmentPropertyList[Yield, Await] : AssignmentProperty[?Yield, ?Await] AssignmentPropertyList[?Yield, ?Await] , AssignmentProperty[?Yield, ?Await] AssignmentElementList[Yield, Await] : AssignmentElisionElement[?Yield, ?Await] AssignmentElementList[?Yield, ?Await] , AssignmentElisionElement[?Yield, ?Await] AssignmentElisionElement[Yield, Await] : Elisionopt AssignmentElement[?Yield, ?Await] AssignmentProperty[Yield, Await] : IdentifierReference[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt PropertyName[?Yield, ?Await] : AssignmentElement[?Yield, ?Await] AssignmentElement[Yield, Await] : DestructuringAssignmentTarget[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt AssignmentRestElement[Yield, Await] : ... DestructuringAssignmentTarget[?Yield, ?Await] DestructuringAssignmentTarget[Yield, Await] : LeftHandSideExpression[?Yield, ?Await]

 

Expression[In, Yield, Await] : AssignmentExpression[?In, ?Yield, ?Await] Expression[?In, ?Yield, ?Await] , AssignmentExpression[?In, ?Yield, ?Await]

A.3 Statements

Statement[Yield, Await, Return] : BlockStatement[?Yield, ?Await, ?Return] VariableStatement[?Yield, ?Await] EmptyStatement ExpressionStatement[?Yield, ?Await] IfStatement[?Yield, ?Await, ?Return] BreakableStatement[?Yield, ?Await, ?Return] ContinueStatement[?Yield, ?Await] BreakStatement[?Yield, ?Await] [+Return] ReturnStatement[?Yield, ?Await] WithStatement[?Yield, ?Await, ?Return] LabelledStatement[?Yield, ?Await, ?Return] ThrowStatement[?Yield, ?Await] TryStatement[?Yield, ?Await, ?Return] DebuggerStatement Declaration[Yield, Await] : HoistableDeclaration[?Yield, ?Await, ~Default] ClassDeclaration[?Yield, ?Await, ~Default] LexicalDeclaration[+In, ?Yield, ?Await] HoistableDeclaration[Yield, Await, Default] : FunctionDeclaration[?Yield, ?Await, ?Default] GeneratorDeclaration[?Yield, ?Await, ?Default] AsyncFunctionDeclaration[?Yield, ?Await, ?Default] AsyncGeneratorDeclaration[?Yield, ?Await, ?Default] BreakableStatement[Yield, Await, Return] : IterationStatement[?Yield, ?Await, ?Return] SwitchStatement[?Yield, ?Await, ?Return] BlockStatement[Yield, Await, Return] : Block[?Yield, ?Await, ?Return] Block[Yield, Await, Return] : { StatementList[?Yield, ?Await, ?Return]opt } StatementList[Yield, Await, Return] : StatementListItem[?Yield, ?Await, ?Return] StatementList[?Yield, ?Await, ?Return] StatementListItem[?Yield, ?Await, ?Return] StatementListItem[Yield, Await, Return] : Statement[?Yield, ?Await, ?Return] Declaration[?Yield, ?Await] LexicalDeclaration[In, Yield, Await] : LetOrConst BindingList[?In, ?Yield, ?Await] ; LetOrConst : let const BindingList[In, Yield, Await] : LexicalBinding[?In, ?Yield, ?Await] BindingList[?In, ?Yield, ?Await] , LexicalBinding[?In, ?Yield, ?Await] LexicalBinding[In, Yield, Await] : BindingIdentifier[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]opt BindingPattern[?Yield, ?Await] Initializer[?In, ?Yield, ?Await] VariableStatement[Yield, Await] : var VariableDeclarationList[+In, ?Yield, ?Await] ; VariableDeclarationList[In, Yield, Await] : VariableDeclaration[?In, ?Yield, ?Await] VariableDeclarationList[?In, ?Yield, ?Await] , VariableDeclaration[?In, ?Yield, ?Await] VariableDeclaration[In, Yield, Await] : BindingIdentifier[?Yield, ?Await] Initializer[?In, ?Yield, ?Await]opt BindingPattern[?Yield, ?Await] Initializer[?In, ?Yield, ?Await] BindingPattern[Yield, Await] : ObjectBindingPattern[?Yield, ?Await] ArrayBindingPattern[?Yield, ?Await] ObjectBindingPattern[Yield, Await] : { } { BindingRestProperty[?Yield, ?Await] } { BindingPropertyList[?Yield, ?Await] } { BindingPropertyList[?Yield, ?Await] , BindingRestProperty[?Yield, ?Await]opt } ArrayBindingPattern[Yield, Await] : [ Elisionopt BindingRestElement[?Yield, ?Await]opt ] [ BindingElementList[?Yield, ?Await] ] [ BindingElementList[?Yield, ?Await] , Elisionopt BindingRestElement[?Yield, ?Await]opt ] BindingRestProperty[Yield, Await] : ... BindingIdentifier[?Yield, ?Await] BindingPropertyList[Yield, Await] : BindingProperty[?Yield, ?Await] BindingPropertyList[?Yield, ?Await] , BindingProperty[?Yield, ?Await] BindingElementList[Yield, Await] : BindingElisionElement[?Yield, ?Await] BindingElementList[?Yield, ?Await] , BindingElisionElement[?Yield, ?Await] BindingElisionElement[Yield, Await] : Elisionopt BindingElement[?Yield, ?Await] BindingProperty[Yield, Await] : SingleNameBinding[?Yield, ?Await] PropertyName[?Yield, ?Await] : BindingElement[?Yield, ?Await] BindingElement[Yield, Await] : SingleNameBinding[?Yield, ?Await] BindingPattern[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt SingleNameBinding[Yield, Await] : BindingIdentifier[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt BindingRestElement[Yield, Await] : ... BindingIdentifier[?Yield, ?Await] ... BindingPattern[?Yield, ?Await] EmptyStatement : ; ExpressionStatement[Yield, Await] : [lookahead ∉ { {, function, async [no LineTerminator here] function, class, let [ }] Expression[+In, ?Yield, ?Await] ; IfStatement[Yield, Await, Return] : if ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] else Statement[?Yield, ?Await, ?Return] if ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] [lookahead ≠ else] IterationStatement[Yield, Await, Return] : DoWhileStatement[?Yield, ?Await, ?Return] WhileStatement[?Yield, ?Await, ?Return] ForStatement[?Yield, ?Await, ?Return] ForInOfStatement[?Yield, ?Await, ?Return] DoWhileStatement[Yield, Await, Return] : do Statement[?Yield, ?Await, ?Return] while ( Expression[+In, ?Yield, ?Await] ) ; WhileStatement[Yield, Await, Return] : while ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] ForStatement[Yield, Await, Return] : for ( [lookahead ≠ let [] Expression[~In, ?Yield, ?Await]opt ; Expression[+In, ?Yield, ?Await]opt ; Expression[+In, ?Yield, ?Await]opt ) Statement[?Yield, ?Await, ?Return] for ( var VariableDeclarationList[~In, ?Yield, ?Await] ; Expression[+In, ?Yield, ?Await]opt ; Expression[+In, ?Yield, ?Await]opt ) Statement[?Yield, ?Await, ?Return] for ( LexicalDeclaration[~In, ?Yield, ?Await] Expression[+In, ?Yield, ?Await]opt ; Expression[+In, ?Yield, ?Await]opt ) Statement[?Yield, ?Await, ?Return] ForInOfStatement[Yield, Await, Return] : for ( [lookahead ≠ let [] LeftHandSideExpression[?Yield, ?Await] in Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( var ForBinding[?Yield, ?Await] in Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( ForDeclaration[?Yield, ?Await] in Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( [lookahead ∉ { let, async of }] LeftHandSideExpression[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( var ForBinding[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] for ( ForDeclaration[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] [+Await] for await ( [lookahead ≠ let] LeftHandSideExpression[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] [+Await] for await ( var ForBinding[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] [+Await] for await ( ForDeclaration[?Yield, ?Await] of AssignmentExpression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] ForDeclaration[Yield, Await] : LetOrConst ForBinding[?Yield, ?Await] ForBinding[Yield, Await] : BindingIdentifier[?Yield, ?Await] BindingPattern[?Yield, ?Await] ContinueStatement[Yield, Await] : continue ; continue [no LineTerminator here] LabelIdentifier[?Yield, ?Await] ; BreakStatement[Yield, Await] : break ; break [no LineTerminator here] LabelIdentifier[?Yield, ?Await] ; ReturnStatement[Yield, Await] : return ; return [no LineTerminator here] Expression[+In, ?Yield, ?Await] ; WithStatement[Yield, Await, Return] : with ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] SwitchStatement[Yield, Await, Return] : switch ( Expression[+In, ?Yield, ?Await] ) CaseBlock[?Yield, ?Await, ?Return] CaseBlock[Yield, Await, Return] : { CaseClauses[?Yield, ?Await, ?Return]opt } { CaseClauses[?Yield, ?Await, ?Return]opt DefaultClause[?Yield, ?Await, ?Return] CaseClauses[?Yield, ?Await, ?Return]opt } CaseClauses[Yield, Await, Return] : CaseClause[?Yield, ?Await, ?Return] CaseClauses[?Yield, ?Await, ?Return] CaseClause[?Yield, ?Await, ?Return] CaseClause[Yield, Await, Return] : case Expression[+In, ?Yield, ?Await] : StatementList[?Yield, ?Await, ?Return]opt DefaultClause[Yield, Await, Return] : default : StatementList[?Yield, ?Await, ?Return]opt LabelledStatement[Yield, Await, Return] : LabelIdentifier[?Yield, ?Await] : LabelledItem[?Yield, ?Await, ?Return] LabelledItem[Yield, Await, Return] : Statement[?Yield, ?Await, ?Return] FunctionDeclaration[?Yield, ?Await, ~Default] ThrowStatement[Yield, Await] : throw [no LineTerminator here] Expression[+In, ?Yield, ?Await] ; TryStatement[Yield, Await, Return] : try Block[?Yield, ?Await, ?Return] Catch[?Yield, ?Await, ?Return] try Block[?Yield, ?Await, ?Return] Finally[?Yield, ?Await, ?Return] try Block[?Yield, ?Await, ?Return] Catch[?Yield, ?Await, ?Return] Finally[?Yield, ?Await, ?Return] Catch[Yield, Await, Return] : catch ( CatchParameter[?Yield, ?Await] ) Block[?Yield, ?Await, ?Return] catch Block[?Yield, ?Await, ?Return] Finally[Yield, Await, Return] : finally Block[?Yield, ?Await, ?Return] CatchParameter[Yield, Await] : BindingIdentifier[?Yield, ?Await] BindingPattern[?Yield, ?Await] DebuggerStatement : debugger ;

A.4 Functions and Classes

UniqueFormalParameters[Yield, Await] : FormalParameters[?Yield, ?Await] FormalParameters[Yield, Await] : [empty] FunctionRestParameter[?Yield, ?Await] FormalParameterList[?Yield, ?Await] FormalParameterList[?Yield, ?Await] , FormalParameterList[?Yield, ?Await] , FunctionRestParameter[?Yield, ?Await] FormalParameterList[Yield, Await] : FormalParameter[?Yield, ?Await] FormalParameterList[?Yield, ?Await] , FormalParameter[?Yield, ?Await] FunctionRestParameter[Yield, Await] : BindingRestElement[?Yield, ?Await] FormalParameter[Yield, Await] : BindingElement[?Yield, ?Await] FunctionDeclaration[Yield, Await, Default] : function BindingIdentifier[?Yield, ?Await] ( FormalParameters[~Yield, ~Await] ) { FunctionBody[~Yield, ~Await] } [+Default] function ( FormalParameters[~Yield, ~Await] ) { FunctionBody[~Yield, ~Await] } FunctionExpression : function BindingIdentifier[~Yield, ~Await]opt ( FormalParameters[~Yield, ~Await] ) { FunctionBody[~Yield, ~Await] } FunctionBody[Yield, Await] : FunctionStatementList[?Yield, ?Await] FunctionStatementList[Yield, Await] : StatementList[?Yield, ?Await, +Return]opt ArrowFunction[In, Yield, Await] : ArrowParameters[?Yield, ?Await] [no LineTerminator here] => ConciseBody[?In] ArrowParameters[Yield, Await] : BindingIdentifier[?Yield, ?Await] CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await] ConciseBody[In] : [lookahead ≠ {] ExpressionBody[?In, ~Await] { FunctionBody[~Yield, ~Await] } ExpressionBody[In, Await] : AssignmentExpression[?In, ~Yield, ?Await]

When processing an instance of the production
ArrowParameters[Yield, Await] : CoverParenthesizedExpressionAndArrowParameterList[?Yield, ?Await]
the interpretation of CoverParenthesizedExpressionAndArrowParameterList is refined using the following grammar:

ArrowFormalParameters[Yield, Await] : ( UniqueFormalParameters[?Yield, ?Await] )

 

AsyncArrowFunction[In, Yield, Await] : async [no LineTerminator here] AsyncArrowBindingIdentifier[?Yield] [no LineTerminator here] => AsyncConciseBody[?In] CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await] [no LineTerminator here] => AsyncConciseBody[?In] AsyncConciseBody[In] : [lookahead ≠ {] ExpressionBody[?In, +Await] { AsyncFunctionBody } AsyncArrowBindingIdentifier[Yield] : BindingIdentifier[?Yield, +Await] CoverCallExpressionAndAsyncArrowHead[Yield, Await] : MemberExpression[?Yield, ?Await] Arguments[?Yield, ?Await]

When processing an instance of the production
AsyncArrowFunction[In, Yield, Await] : CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await] [no LineTerminator here] => AsyncConciseBody[?In]
the interpretation of CoverCallExpressionAndAsyncArrowHead is refined using the following grammar:

AsyncArrowHead : async [no LineTerminator here] ArrowFormalParameters[~Yield, +Await]

 

MethodDefinition[Yield, Await] : ClassElementName[?Yield, ?Await] ( UniqueFormalParameters[~Yield, ~Await] ) { FunctionBody[~Yield, ~Await] } GeneratorMethod[?Yield, ?Await] AsyncMethod[?Yield, ?Await] AsyncGeneratorMethod[?Yield, ?Await] get ClassElementName[?Yield, ?Await] ( ) { FunctionBody[~Yield, ~Await] } set ClassElementName[?Yield, ?Await] ( PropertySetParameterList ) { FunctionBody[~Yield, ~Await] } PropertySetParameterList : FormalParameter[~Yield, ~Await] GeneratorDeclaration[Yield, Await, Default] : function * BindingIdentifier[?Yield, ?Await] ( FormalParameters[+Yield, ~Await] ) { GeneratorBody } [+Default] function * ( FormalParameters[+Yield, ~Await] ) { GeneratorBody } GeneratorExpression : function * BindingIdentifier[+Yield, ~Await]opt ( FormalParameters[+Yield, ~Await] ) { GeneratorBody } GeneratorMethod[Yield, Await] : * ClassElementName[?Yield, ?Await] ( UniqueFormalParameters[+Yield, ~Await] ) { GeneratorBody } GeneratorBody : FunctionBody[+Yield, ~Await] YieldExpression[In, Await] : yield yield [no LineTerminator here] AssignmentExpression[?In, +Yield, ?Await] yield [no LineTerminator here] * AssignmentExpression[?In, +Yield, ?Await] AsyncGeneratorDeclaration[Yield, Await, Default] : async [no LineTerminator here] function * BindingIdentifier[?Yield, ?Await] ( FormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } [+Default] async [no LineTerminator here] function * ( FormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } AsyncGeneratorExpression : async [no LineTerminator here] function * BindingIdentifier[+Yield, +Await]opt ( FormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } AsyncGeneratorMethod[Yield, Await] : async [no LineTerminator here] * ClassElementName[?Yield, ?Await] ( UniqueFormalParameters[+Yield, +Await] ) { AsyncGeneratorBody } AsyncGeneratorBody : FunctionBody[+Yield, +Await] AsyncFunctionDeclaration[Yield, Await, Default] : async [no LineTerminator here] function BindingIdentifier[?Yield, ?Await] ( FormalParameters[~Yield, +Await] ) { AsyncFunctionBody } [+Default] async [no LineTerminator here] function ( FormalParameters[~Yield, +Await] ) { AsyncFunctionBody } AsyncFunctionExpression : async [no LineTerminator here] function BindingIdentifier[~Yield, +Await]opt ( FormalParameters[~Yield, +Await] ) { AsyncFunctionBody } AsyncMethod[Yield, Await] : async [no LineTerminator here] ClassElementName[?Yield, ?Await] ( UniqueFormalParameters[~Yield, +Await] ) { AsyncFunctionBody } AsyncFunctionBody : FunctionBody[~Yield, +Await] AwaitExpression[Yield] : await UnaryExpression[?Yield, +Await] ClassDeclaration[Yield, Await, Default] : class BindingIdentifier[?Yield, ?Await] ClassTail[?Yield, ?Await] [+Default] class ClassTail[?Yield, ?Await] ClassExpression[Yield, Await] : class BindingIdentifier[?Yield, ?Await]opt ClassTail[?Yield, ?Await] ClassTail[Yield, Await] : ClassHeritage[?Yield, ?Await]opt { ClassBody[?Yield, ?Await]opt } ClassHeritage[Yield, Await] : extends LeftHandSideExpression[?Yield, ?Await] ClassBody[Yield, Await] : ClassElementList[?Yield, ?Await] ClassElementList[Yield, Await] : ClassElement[?Yield, ?Await] ClassElementList[?Yield, ?Await] ClassElement[?Yield, ?Await] ClassElement[Yield, Await] : MethodDefinition[?Yield, ?Await] static MethodDefinition[?Yield, ?Await] FieldDefinition[?Yield, ?Await] ; static FieldDefinition[?Yield, ?Await] ; ClassStaticBlock ; FieldDefinition[Yield, Await] : ClassElementName[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt ClassElementName[Yield, Await] : PropertyName[?Yield, ?Await] PrivateIdentifier ClassStaticBlock : static { ClassStaticBlockBody } ClassStaticBlockBody : ClassStaticBlockStatementList ClassStaticBlockStatementList : StatementList[~Yield, +Await, ~Return]opt

A.5 Scripts and Modules

Script : ScriptBodyopt ScriptBody : StatementList[~Yield, ~Await, ~Return] Module : ModuleBodyopt ModuleBody : ModuleItemList ModuleItemList : ModuleItem ModuleItemList ModuleItem ModuleItem : ImportDeclaration ExportDeclaration StatementListItem[~Yield, +Await, ~Return] ModuleExportName : IdentifierName StringLiteral ImportDeclaration : import ImportClause FromClause WithClauseopt ; import ModuleSpecifier WithClauseopt ; ImportClause : ImportedDefaultBinding NameSpaceImport NamedImports ImportedDefaultBinding , NameSpaceImport ImportedDefaultBinding , NamedImports ImportedDefaultBinding : ImportedBinding NameSpaceImport : * as ImportedBinding NamedImports : { } { ImportsList } { ImportsList , } FromClause : from ModuleSpecifier ImportsList : ImportSpecifier ImportsList , ImportSpecifier ImportSpecifier : ImportedBinding ModuleExportName as ImportedBinding ModuleSpecifier : StringLiteral ImportedBinding : BindingIdentifier[~Yield, +Await] WithClause : with { } with { WithEntries ,opt } WithEntries : AttributeKey : StringLiteral AttributeKey : StringLiteral , WithEntries AttributeKey : IdentifierName StringLiteral ExportDeclaration : export ExportFromClause FromClause WithClauseopt ; export NamedExports ; export VariableStatement[~Yield, +Await] export Declaration[~Yield, +Await] export default HoistableDeclaration[~Yield, +Await, +Default] export default ClassDeclaration[~Yield, +Await, +Default] export default [lookahead ∉ { function, async [no LineTerminator here] function, class }] AssignmentExpression[+In, ~Yield, +Await] ; ExportFromClause : * * as ModuleExportName NamedExports NamedExports : { } { ExportsList } { ExportsList , } ExportsList : ExportSpecifier ExportsList , ExportSpecifier ExportSpecifier : ModuleExportName ModuleExportName as ModuleExportName

A.6 Number Conversions

StringNumericLiteral ::: StrWhiteSpaceopt StrWhiteSpaceopt StrNumericLiteral StrWhiteSpaceopt StrWhiteSpace ::: StrWhiteSpaceChar StrWhiteSpaceopt StrWhiteSpaceChar ::: WhiteSpace LineTerminator StrNumericLiteral ::: StrDecimalLiteral NonDecimalIntegerLiteral[~Sep] StrDecimalLiteral ::: StrUnsignedDecimalLiteral + StrUnsignedDecimalLiteral - StrUnsignedDecimalLiteral StrUnsignedDecimalLiteral ::: Infinity DecimalDigits[~Sep] . DecimalDigits[~Sep]opt ExponentPart[~Sep]opt . DecimalDigits[~Sep] ExponentPart[~Sep]opt DecimalDigits[~Sep] ExponentPart[~Sep]opt

All grammar symbols not explicitly defined by the StringNumericLiteral grammar have the definitions used in the Lexical Grammar for numeric literals.

StringIntegerLiteral ::: StrWhiteSpaceopt StrWhiteSpaceopt StrIntegerLiteral StrWhiteSpaceopt StrIntegerLiteral ::: SignedInteger[~Sep] NonDecimalIntegerLiteral[~Sep]

A.7 Time Zone Offset String Format

UTCOffset ::: ASCIISign Hour ASCIISign Hour HourSubcomponents[+Extended] ASCIISign Hour HourSubcomponents[~Extended] ASCIISign ::: one of + - Hour ::: 0 DecimalDigit 1 DecimalDigit 20 21 22 23 HourSubcomponents[Extended] ::: TimeSeparator[?Extended] MinuteSecond TimeSeparator[?Extended] MinuteSecond TimeSeparator[?Extended] MinuteSecond TemporalDecimalFractionopt TimeSeparator[Extended] ::: [+Extended] : [~Extended] [empty] MinuteSecond ::: 0 DecimalDigit 1 DecimalDigit 2 DecimalDigit 3 DecimalDigit 4 DecimalDigit 5 DecimalDigit TemporalDecimalFraction ::: TemporalDecimalSeparator DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit DecimalDigit TemporalDecimalSeparator ::: one of . ,

A.8 Regular Expressions

Pattern[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Disjunction[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: Alternative[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Alternative[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] | Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Alternative[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: [empty] Alternative[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Term[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Term[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: Assertion[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Atom[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Atom[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Quantifier Assertion[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: ^ $ \b \B (?= Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) (?! Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) (?<= Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) (?<! Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) Quantifier :: QuantifierPrefix QuantifierPrefix ? QuantifierPrefix :: * + ? { DecimalDigits[~Sep] } { DecimalDigits[~Sep] ,} { DecimalDigits[~Sep] , DecimalDigits[~Sep] } Atom[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: PatternCharacter . \ AtomEscape[?UnicodeMode, ?NamedCaptureGroups] CharacterClass[?UnicodeMode, ?UnicodeSetsMode] ( GroupSpecifier[?UnicodeMode]opt Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) (? RegularExpressionModifiers : Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) (? RegularExpressionModifiers - RegularExpressionModifiers : Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) RegularExpressionModifiers :: [empty] RegularExpressionModifiers RegularExpressionModifier RegularExpressionModifier :: one of i m s SyntaxCharacter :: one of ^ $ \ . * + ? ( ) [ ] { } | PatternCharacter :: SourceCharacter but not SyntaxCharacter AtomEscape[UnicodeMode, NamedCaptureGroups] :: DecimalEscape CharacterClassEscape[?UnicodeMode] CharacterEscape[?UnicodeMode] [+NamedCaptureGroups] k GroupName[?UnicodeMode] CharacterEscape[UnicodeMode] :: ControlEscape c AsciiLetter 0 [lookahead ∉ DecimalDigit] HexEscapeSequence RegExpUnicodeEscapeSequence[?UnicodeMode] IdentityEscape[?UnicodeMode] ControlEscape :: one of f n r t v GroupSpecifier[UnicodeMode] :: ? GroupName[?UnicodeMode] GroupName[UnicodeMode] :: < RegExpIdentifierName[?UnicodeMode] > RegExpIdentifierName[UnicodeMode] :: RegExpIdentifierStart[?UnicodeMode] RegExpIdentifierName[?UnicodeMode] RegExpIdentifierPart[?UnicodeMode] RegExpIdentifierStart[UnicodeMode] :: IdentifierStartChar \ RegExpUnicodeEscapeSequence[+UnicodeMode] [~UnicodeMode] UnicodeLeadSurrogate UnicodeTrailSurrogate RegExpIdentifierPart[UnicodeMode] :: IdentifierPartChar \ RegExpUnicodeEscapeSequence[+UnicodeMode] [~UnicodeMode] UnicodeLeadSurrogate UnicodeTrailSurrogate RegExpUnicodeEscapeSequence[UnicodeMode] :: [+UnicodeMode] u HexLeadSurrogate \u HexTrailSurrogate [+UnicodeMode] u HexLeadSurrogate [+UnicodeMode] u HexTrailSurrogate [+UnicodeMode] u HexNonSurrogate [~UnicodeMode] u Hex4Digits [+UnicodeMode] u{ CodePoint } UnicodeLeadSurrogate :: any Unicode code point in the inclusive interval from U+D800 to U+DBFF UnicodeTrailSurrogate :: any Unicode code point in the inclusive interval from U+DC00 to U+DFFF

Each \u HexTrailSurrogate for which the choice of associated u HexLeadSurrogate is ambiguous shall be associated with the nearest possible u HexLeadSurrogate that would otherwise have no corresponding \u HexTrailSurrogate.

 

HexLeadSurrogate :: Hex4Digits but only if the MV of Hex4Digits is in the inclusive interval from 0xD800 to 0xDBFF HexTrailSurrogate :: Hex4Digits but only if the MV of Hex4Digits is in the inclusive interval from 0xDC00 to 0xDFFF HexNonSurrogate :: Hex4Digits but only if the MV of Hex4Digits is not in the inclusive interval from 0xD800 to 0xDFFF IdentityEscape[UnicodeMode] :: [+UnicodeMode] SyntaxCharacter [+UnicodeMode] / [~UnicodeMode] SourceCharacter but not UnicodeIDContinue DecimalEscape :: NonZeroDigit DecimalDigits[~Sep]opt [lookahead ∉ DecimalDigit] CharacterClassEscape[UnicodeMode] :: d D s S w W [+UnicodeMode] p{ UnicodePropertyValueExpression } [+UnicodeMode] P{ UnicodePropertyValueExpression } UnicodePropertyValueExpression :: UnicodePropertyName = UnicodePropertyValue LoneUnicodePropertyNameOrValue UnicodePropertyName :: UnicodePropertyNameCharacters UnicodePropertyNameCharacters :: UnicodePropertyNameCharacter UnicodePropertyNameCharactersopt UnicodePropertyValue :: UnicodePropertyValueCharacters LoneUnicodePropertyNameOrValue :: UnicodePropertyValueCharacters UnicodePropertyValueCharacters :: UnicodePropertyValueCharacter UnicodePropertyValueCharactersopt UnicodePropertyValueCharacter :: UnicodePropertyNameCharacter DecimalDigit UnicodePropertyNameCharacter :: AsciiLetter _ CharacterClass[UnicodeMode, UnicodeSetsMode] :: [ [lookahead ≠ ^] ClassContents[?UnicodeMode, ?UnicodeSetsMode] ] [^ ClassContents[?UnicodeMode, ?UnicodeSetsMode] ] ClassContents[UnicodeMode, UnicodeSetsMode] :: [empty] [~UnicodeSetsMode] NonemptyClassRanges[?UnicodeMode] [+UnicodeSetsMode] ClassSetExpression NonemptyClassRanges[UnicodeMode] :: ClassAtom[?UnicodeMode] ClassAtom[?UnicodeMode] NonemptyClassRangesNoDash[?UnicodeMode] ClassAtom[?UnicodeMode] - ClassAtom[?UnicodeMode] ClassContents[?UnicodeMode, ~UnicodeSetsMode] NonemptyClassRangesNoDash[UnicodeMode] :: ClassAtom[?UnicodeMode] ClassAtomNoDash[?UnicodeMode] NonemptyClassRangesNoDash[?UnicodeMode] ClassAtomNoDash[?UnicodeMode] - ClassAtom[?UnicodeMode] ClassContents[?UnicodeMode, ~UnicodeSetsMode] ClassAtom[UnicodeMode] :: - ClassAtomNoDash[?UnicodeMode] ClassAtomNoDash[UnicodeMode] :: SourceCharacter but not one of \ or ] or - \ ClassEscape[?UnicodeMode] ClassEscape[UnicodeMode] :: b [+UnicodeMode] - CharacterClassEscape[?UnicodeMode] CharacterEscape[?UnicodeMode] ClassSetExpression :: ClassUnion ClassIntersection ClassSubtraction ClassUnion :: ClassSetRange ClassUnionopt ClassSetOperand ClassUnionopt ClassIntersection :: ClassSetOperand && [lookahead ≠ &] ClassSetOperand ClassIntersection && [lookahead ≠ &] ClassSetOperand ClassSubtraction :: ClassSetOperand -- ClassSetOperand ClassSubtraction -- ClassSetOperand ClassSetRange :: ClassSetCharacter - ClassSetCharacter ClassSetOperand :: NestedClass ClassStringDisjunction ClassSetCharacter NestedClass :: [ [lookahead ≠ ^] ClassContents[+UnicodeMode, +UnicodeSetsMode] ] [^ ClassContents[+UnicodeMode, +UnicodeSetsMode] ] \ CharacterClassEscape[+UnicodeMode] ClassStringDisjunction :: \q{ ClassStringDisjunctionContents } ClassStringDisjunctionContents :: ClassString ClassString | ClassStringDisjunctionContents ClassString :: [empty] NonEmptyClassString NonEmptyClassString :: ClassSetCharacter NonEmptyClassStringopt ClassSetCharacter :: [lookahead ∉ ClassSetReservedDoublePunctuator] SourceCharacter but not ClassSetSyntaxCharacter \ CharacterEscape[+UnicodeMode] \ ClassSetReservedPunctuator \b ClassSetReservedDoublePunctuator :: one of && !! ## $$ %% ** ++ ,, .. :: ;; << == >> ?? @@ ^^ `` ~~ ClassSetSyntaxCharacter :: one of ( ) [ ] { } / - \ | ClassSetReservedPunctuator :: one of & - ! # % , : ; < = > @ ` ~

Annex B (normative) Additional ECMAScript Features for Web Browsers

The ECMAScript language syntax and semantics defined in this annex are required when the ECMAScript host is a web browser. The content of this annex is normative but optional if the ECMAScript host is not a web browser.

Note

This annex describes various legacy features and other characteristics of web browser ECMAScript hosts. All of the language features and behaviours specified in this annex have one or more undesirable characteristics and in the absence of legacy usage would be removed from this specification. However, the usage of these features by large numbers of existing web pages means that web browsers must continue to support them. The specifications in this annex define the requirements for interoperable implementations of these legacy features.

These features are not considered part of the core ECMAScript language. Programmers should not use or assume the existence of these features and behaviours when writing new ECMAScript code. ECMAScript implementations are discouraged from implementing these features unless the implementation is part of a web browser or is required to run the same legacy ECMAScript code that web browsers encounter.

B.1 Additional Syntax

B.1.1 HTML-like Comments

The syntax and semantics of 12.4 is extended as follows except that this extension is not allowed when parsing source text using the goal symbol Module:

Syntax

InputElementHashbangOrRegExp :: WhiteSpace LineTerminator Comment CommonToken HashbangComment RegularExpressionLiteral HTMLCloseComment Comment :: MultiLineComment SingleLineComment SingleLineHTMLOpenComment SingleLineHTMLCloseComment SingleLineDelimitedComment MultiLineComment :: /* FirstCommentLineopt LineTerminator MultiLineCommentCharsopt */ HTMLCloseCommentopt FirstCommentLine :: SingleLineDelimitedCommentChars SingleLineHTMLOpenComment :: <!-- SingleLineCommentCharsopt SingleLineHTMLCloseComment :: LineTerminatorSequence HTMLCloseComment SingleLineDelimitedComment :: /* SingleLineDelimitedCommentCharsopt */ HTMLCloseComment :: WhiteSpaceSequenceopt SingleLineDelimitedCommentSequenceopt --> SingleLineCommentCharsopt SingleLineDelimitedCommentChars :: SingleLineNotAsteriskChar SingleLineDelimitedCommentCharsopt * SingleLinePostAsteriskCommentCharsopt SingleLineNotAsteriskChar :: SourceCharacter but not one of * or LineTerminator SingleLinePostAsteriskCommentChars :: SingleLineNotForwardSlashOrAsteriskChar SingleLineDelimitedCommentCharsopt * SingleLinePostAsteriskCommentCharsopt SingleLineNotForwardSlashOrAsteriskChar :: SourceCharacter but not one of / or * or LineTerminator WhiteSpaceSequence :: WhiteSpace WhiteSpaceSequenceopt SingleLineDelimitedCommentSequence :: SingleLineDelimitedComment WhiteSpaceSequenceopt SingleLineDelimitedCommentSequenceopt

Similar to a MultiLineComment that contains a line terminator code point, a SingleLineHTMLCloseComment is considered to be a LineTerminator for purposes of parsing by the syntactic grammar.

B.1.2 Regular Expressions Patterns

The syntax of 22.2.1 is modified and extended as follows. These changes introduce ambiguities that are broken by the ordering of grammar productions and by contextual information. When parsing using the following grammar, each alternative is considered only if previous production alternatives do not match.

This alternative pattern grammar and semantics only changes the syntax and semantics of BMP patterns. The following grammar extensions include productions parameterized with the [UnicodeMode] parameter. However, none of these extensions change the syntax of Unicode patterns recognized when parsing with the [UnicodeMode] parameter present on the goal symbol.

Syntax

Term[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: [+UnicodeMode] Assertion[+UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] [+UnicodeMode] Atom[+UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] Quantifier [+UnicodeMode] Atom[+UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] [~UnicodeMode] QuantifiableAssertion[?NamedCaptureGroups] Quantifier [~UnicodeMode] Assertion[~UnicodeMode, ~UnicodeSetsMode, ?NamedCaptureGroups] [~UnicodeMode] ExtendedAtom[?NamedCaptureGroups] Quantifier [~UnicodeMode] ExtendedAtom[?NamedCaptureGroups] Assertion[UnicodeMode, UnicodeSetsMode, NamedCaptureGroups] :: ^ $ \b \B [+UnicodeMode] (?= Disjunction[+UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) [+UnicodeMode] (?! Disjunction[+UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) [~UnicodeMode] QuantifiableAssertion[?NamedCaptureGroups] (?<= Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) (?<! Disjunction[?UnicodeMode, ?UnicodeSetsMode, ?NamedCaptureGroups] ) QuantifiableAssertion[NamedCaptureGroups] :: (?= Disjunction[~UnicodeMode, ~UnicodeSetsMode, ?NamedCaptureGroups] ) (?! Disjunction[~UnicodeMode, ~UnicodeSetsMode, ?NamedCaptureGroups] ) ExtendedAtom[NamedCaptureGroups] :: . \ AtomEscape[~UnicodeMode, ?NamedCaptureGroups] \ [lookahead = c] CharacterClass[~UnicodeMode, ~UnicodeSetsMode] ( GroupSpecifier[~UnicodeMode]opt Disjunction[~UnicodeMode, ~UnicodeSetsMode, ?NamedCaptureGroups] ) (? RegularExpressionModifiers : Disjunction[~UnicodeMode, ~UnicodeSetsMode, ?NamedCaptureGroups] ) (? RegularExpressionModifiers - RegularExpressionModifiers : Disjunction[~UnicodeMode, ~UnicodeSetsMode, ?NamedCaptureGroups] ) InvalidBracedQuantifier ExtendedPatternCharacter InvalidBracedQuantifier :: { DecimalDigits[~Sep] } { DecimalDigits[~Sep] ,} { DecimalDigits[~Sep] , DecimalDigits[~Sep] } ExtendedPatternCharacter :: SourceCharacter but not one of ^ $ \ . * + ? ( ) [ | AtomEscape[UnicodeMode, NamedCaptureGroups] :: [+UnicodeMode] DecimalEscape [~UnicodeMode] DecimalEscape but only if the CapturingGroupNumber of DecimalEscape is ≤ CountLeftCapturingParensWithin(the Pattern containing DecimalEscape) CharacterClassEscape[?UnicodeMode] CharacterEscape[?UnicodeMode, ?NamedCaptureGroups] [+NamedCaptureGroups] k GroupName[?UnicodeMode] CharacterEscape[UnicodeMode, NamedCaptureGroups] :: ControlEscape c AsciiLetter 0 [lookahead ∉ DecimalDigit] HexEscapeSequence RegExpUnicodeEscapeSequence[?UnicodeMode] [~UnicodeMode] LegacyOctalEscapeSequence IdentityEscape[?UnicodeMode, ?NamedCaptureGroups] IdentityEscape[UnicodeMode, NamedCaptureGroups] :: [+UnicodeMode] SyntaxCharacter [+UnicodeMode] / [~UnicodeMode] SourceCharacterIdentityEscape[?NamedCaptureGroups] SourceCharacterIdentityEscape[NamedCaptureGroups] :: [~NamedCaptureGroups] SourceCharacter but not c [+NamedCaptureGroups] SourceCharacter but not one of c or k ClassAtomNoDash[UnicodeMode, NamedCaptureGroups] :: SourceCharacter but not one of \ or ] or - \ ClassEscape[?UnicodeMode, ?NamedCaptureGroups] \ [lookahead = c] ClassEscape[UnicodeMode, NamedCaptureGroups] :: b [+UnicodeMode] - [~UnicodeMode] c ClassControlLetter CharacterClassEscape[?UnicodeMode] CharacterEscape[?UnicodeMode, ?NamedCaptureGroups] ClassControlLetter :: DecimalDigit _ Note

When the same left-hand sides occurs with both [+UnicodeMode] and [~UnicodeMode] guards it is to control the disambiguation priority.

B.1.2.1 Static Semantics: Early Errors

The semantics of 22.2.1.1 is extended as follows:

ExtendedAtom :: InvalidBracedQuantifier
  • It is a Syntax Error if any source text is matched by this production.

Additionally, the rules for the following productions are modified with the addition of the highlighted text:

NonemptyClassRanges :: ClassAtom - ClassAtom ClassContents NonemptyClassRangesNoDash :: ClassAtomNoDash - ClassAtom ClassContents

B.1.2.2 Static Semantics: CountLeftCapturingParensWithin and CountLeftCapturingParensBefore

In the definitions of CountLeftCapturingParensWithin and CountLeftCapturingParensBefore, references to “ Atom :: ( GroupSpecifieropt Disjunction ) ” are to be interpreted as meaning “ Atom :: ( GroupSpecifieropt Disjunction ) ” or “ ExtendedAtom :: ( GroupSpecifieropt Disjunction ) ”.

B.1.2.3 Static Semantics: IsCharacterClass

The semantics of 22.2.1.6 is extended as follows:

ClassAtomNoDash :: \ [lookahead = c]
  1. Return false.

B.1.2.4 Static Semantics: CharacterValue

The semantics of 22.2.1.7 is extended as follows:

ClassAtomNoDash :: \ [lookahead = c]
  1. Return the numeric value of U+005C (REVERSE SOLIDUS).
ClassEscape :: c ClassControlLetter
  1. Let ch be the code point matched by ClassControlLetter.
  2. Let i be the numeric value of ch.
  3. Return the remainder of dividing i by 32.
CharacterEscape :: LegacyOctalEscapeSequence
  1. Return the MV of LegacyOctalEscapeSequence (see 12.9.4.3).

B.1.2.5 Runtime Semantics: CompileSubpattern

The semantics of CompileSubpattern is extended as follows:

The rule for Term :: QuantifiableAssertion Quantifier is the same as for Term :: Atom Quantifier but with QuantifiableAssertion substituted for Atom.

The rule for Term :: ExtendedAtom Quantifier is the same as for Term :: Atom Quantifier but with ExtendedAtom substituted for Atom.

The rule for Term :: ExtendedAtom is the same as for Term :: Atom but with ExtendedAtom substituted for Atom.

B.1.2.6 Runtime Semantics: CompileAssertion

CompileAssertion rules for the Assertion :: (?= Disjunction ) and Assertion :: (?! Disjunction ) productions are also used for the QuantifiableAssertion productions, but with QuantifiableAssertion substituted for Assertion.

B.1.2.7 Runtime Semantics: CompileAtom

CompileAtom rules for the Atom productions except for Atom :: PatternCharacter are also used for the ExtendedAtom productions, but with ExtendedAtom substituted for Atom. The following rules, with parameter direction, are also added:

ExtendedAtom :: \ [lookahead = c]
  1. Let A be the CharSet containing the single character \ U+005C (REVERSE SOLIDUS).
  2. Return CharacterSetMatcher(rer, A, false, direction).
ExtendedAtom :: ExtendedPatternCharacter
  1. Let ch be the character represented by ExtendedPatternCharacter.
  2. Let A be a one-element CharSet containing the character ch.
  3. Return CharacterSetMatcher(rer, A, false, direction).

B.1.2.8 Runtime Semantics: CompileToCharSet

The semantics of 22.2.2.9 is extended as follows:

The following two rules replace the corresponding rules of CompileToCharSet.

NonemptyClassRanges :: ClassAtom - ClassAtom ClassContents
  1. Let A be CompileToCharSet of the first ClassAtom with argument rer.
  2. Let B be CompileToCharSet of the second ClassAtom with argument rer.
  3. Let C be CompileToCharSet of ClassContents with argument rer.
  4. Let D be CharacterRangeOrUnion(rer, A, B).
  5. Return the union of D and C.
NonemptyClassRangesNoDash :: ClassAtomNoDash - ClassAtom ClassContents
  1. Let A be CompileToCharSet of ClassAtomNoDash with argument rer.
  2. Let B be CompileToCharSet of ClassAtom with argument rer.
  3. Let C be CompileToCharSet of ClassContents with argument rer.
  4. Let D be CharacterRangeOrUnion(rer, A, B).
  5. Return the union of D and C.

In addition, the following rules are added to CompileToCharSet.

ClassEscape :: c ClassControlLetter
  1. Let cv be the CharacterValue of this ClassEscape.
  2. Let c be the character whose character value is cv.
  3. Return the CharSet containing the single character c.
ClassAtomNoDash :: \ [lookahead = c]
  1. Return the CharSet containing the single character \ U+005C (REVERSE SOLIDUS).
Note
This production can only be reached from the sequence \c within a character class where it is not followed by an acceptable control character.

B.1.2.8.1 CharacterRangeOrUnion ( rer, A, B )

The abstract operation CharacterRangeOrUnion takes arguments rer (a RegExp Record), A (a CharSet), and B (a CharSet) and returns a CharSet. It performs the following steps when called:

  1. If HasEitherUnicodeFlag(rer) is false, then
    1. If A does not contain exactly one character or B does not contain exactly one character, then
      1. Let C be the CharSet containing the single character - U+002D (HYPHEN-MINUS).
      2. Return the union of CharSets A, B and C.
  2. Return CharacterRange(A, B).

B.1.2.9 Static Semantics: ParsePattern ( patternText, u, v )

The semantics of 22.2.3.4 is extended as follows:

The abstract operation ParsePattern takes arguments patternText (a sequence of Unicode code points), u (a Boolean), and v (a Boolean). It performs the following steps when called:

  1. If v is true and u is true, then
    1. Let parseResult be a List containing one or more SyntaxError objects.
  2. Else if v is true, then
    1. Let parseResult be ParseText(patternText, Pattern[+UnicodeMode, +UnicodeSetsMode, +NamedCaptureGroups]).
  3. Else if u is true, then
    1. Let parseResult be ParseText(patternText, Pattern[+UnicodeMode, ~UnicodeSetsMode, +NamedCaptureGroups]).
  4. Else,
    1. Let parseResult be ParseText(patternText, Pattern[~UnicodeMode, ~UnicodeSetsMode, ~NamedCaptureGroups]).
    2. If parseResult is a Parse Node and parseResult contains a GroupName, then
      1. Set parseResult to ParseText(patternText, Pattern[~UnicodeMode, ~UnicodeSetsMode, +NamedCaptureGroups]).
  5. Return parseResult.

B.2 Additional Built-in Properties

When the ECMAScript host is a web browser the following additional properties of the standard built-in objects are defined.

B.2.1 Additional Properties of the Global Object

The entries in Table 102 are added to Table 6.

Table 102: Additional Well-known Intrinsic Objects
Intrinsic Name Global Name ECMAScript Language Association
%escape% escape The escape function (B.2.1.1)
%unescape% unescape The unescape function (B.2.1.2)

B.2.1.1 escape ( string )

This function is a property of the global object. It computes a new version of a String value in which certain code units have been replaced by a hexadecimal escape sequence.

When replacing a code unit of numeric value less than or equal to 0x00FF, a two-digit escape sequence of the form %xx is used. When replacing a code unit of numeric value strictly greater than 0x00FF, a four-digit escape sequence of the form %uxxxx is used.

It is the %escape% intrinsic object.

It performs the following steps when called:

  1. Set string to ? ToString(string).
  2. Let len be the length of string.
  3. Let R be the empty String.
  4. Let unescapedSet be the string-concatenation of the ASCII word characters and "@*+-./".
  5. Let k be 0.
  6. Repeat, while k < len,
    1. Let C be the code unit at index k within string.
    2. If unescapedSet contains C, then
      1. Let S be C.
    3. Else,
      1. Let n be the numeric value of C.
      2. If n < 256, then
        1. Let hex be the String representation of n, formatted as an uppercase hexadecimal number.
        2. Let S be the string-concatenation of "%" and StringPad(hex, 2, "0", start).
      3. Else,
        1. Let hex be the String representation of n, formatted as an uppercase hexadecimal number.
        2. Let S be the string-concatenation of "%u" and StringPad(hex, 4, "0", start).
    4. Set R to the string-concatenation of R and S.
    5. Set k to k + 1.
  7. Return R.
Note

The encoding is partly based on the encoding described in RFC 1738, but the entire encoding specified in this standard is described above without regard to the contents of RFC 1738. This encoding does not reflect changes to RFC 1738 made by RFC 3986.

B.2.1.2 unescape ( string )

This function is a property of the global object. It computes a new version of a String value in which each escape sequence of the sort that might be introduced by the escape function is replaced with the code unit that it represents.

It is the %unescape% intrinsic object.

It performs the following steps when called:

  1. Set string to ? ToString(string).
  2. Let len be the length of string.
  3. Let R be the empty String.
  4. Let k be 0.
  5. Repeat, while k < len,
    1. Let C be the code unit at index k within string.
    2. If C is the code unit 0x0025 (PERCENT SIGN), then
      1. Let hexDigits be the empty String.
      2. Let optionalAdvance be 0.
      3. If k + 5 < len and the code unit at index k + 1 within string is the code unit 0x0075 (LATIN SMALL LETTER U), then
        1. Set hexDigits to the substring of string from k + 2 to k + 6.
        2. Set optionalAdvance to 5.
      4. Else if k + 3 ≤ len, then
        1. Set hexDigits to the substring of string from k + 1 to k + 3.
        2. Set optionalAdvance to 2.
      5. Let parseResult be ParseText(hexDigits, HexDigits[~Sep]).
      6. If parseResult is a Parse Node, then
        1. Let n be the MV of parseResult.
        2. Set C to the code unit whose numeric value is n.
        3. Set k to k + optionalAdvance.
    3. Set R to the string-concatenation of R and C.
    4. Set k to k + 1.
  6. Return R.

B.2.2 Additional Properties of the String.prototype Object

B.2.2.1 String.prototype.substr ( start, length )

This method returns a substring of the result of converting the this value to a String, starting from index start and running for length code units (or through the end of the String if length is undefined). If start is negative, it is treated as sourceLength + start where sourceLength is the length of the String. The result is a String value, not a String object.

It performs the following steps when called:

  1. Let O be ? RequireObjectCoercible(this value).
  2. Let S be ? ToString(O).
  3. Let size be the length of S.
  4. Let intStart be ? ToIntegerOrInfinity(start).
  5. If intStart = -∞, set intStart to 0.
  6. Else if intStart < 0, set intStart to max(size + intStart, 0).
  7. Else, set intStart to min(intStart, size).
  8. If length is undefined, let intLength be size; otherwise let intLength be ? ToIntegerOrInfinity(length).
  9. Set intLength to the result of clamping intLength between 0 and size.
  10. Let intEnd be min(intStart + intLength, size).
  11. Return the substring of S from intStart to intEnd.
Note

This method is intentionally generic; it does not require that its this value be a String object. Therefore it can be transferred to other kinds of objects for use as a method.

B.2.2.2 String.prototype.anchor ( name )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "a", "name", name).

B.2.2.2.1 CreateHTML ( string, tag, attribute, value )

The abstract operation CreateHTML takes arguments string (an ECMAScript language value), tag (a String), attribute (a String), and value (an ECMAScript language value) and returns either a normal completion containing a String or a throw completion. It performs the following steps when called:

  1. Let str be ? RequireObjectCoercible(string).
  2. Let S be ? ToString(str).
  3. Let p1 be the string-concatenation of "<" and tag.
  4. If attribute is not the empty String, then
    1. Let V be ? ToString(value).
    2. Let escapedV be the String value that is the same as V except that each occurrence of the code unit 0x0022 (QUOTATION MARK) in V has been replaced with the six code unit sequence "&quot;".
    3. Set p1 to the string-concatenation of:
      • p1
      • the code unit 0x0020 (SPACE)
      • attribute
      • the code unit 0x003D (EQUALS SIGN)
      • the code unit 0x0022 (QUOTATION MARK)
      • escapedV
      • the code unit 0x0022 (QUOTATION MARK)
  5. Let p2 be the string-concatenation of p1 and ">".
  6. Let p3 be the string-concatenation of p2 and S.
  7. Let p4 be the string-concatenation of p3, "</", tag, and ">".
  8. Return p4.

B.2.2.3 String.prototype.big ( )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "big", "", "").

B.2.2.4 String.prototype.blink ( )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "blink", "", "").

B.2.2.5 String.prototype.bold ( )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "b", "", "").

B.2.2.6 String.prototype.fixed ( )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "tt", "", "").

B.2.2.7 String.prototype.fontcolor ( colour )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "font", "color", colour).

B.2.2.8 String.prototype.fontsize ( size )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "font", "size", size).

B.2.2.9 String.prototype.italics ( )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "i", "", "").

B.2.2.10 String.prototype.link ( url )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "a", "href", url).

B.2.2.11 String.prototype.small ( )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "small", "", "").

B.2.2.12 String.prototype.strike ( )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "strike", "", "").

B.2.2.13 String.prototype.sub ( )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "sub", "", "").

B.2.2.14 String.prototype.sup ( )

This method performs the following steps when called:

  1. Let S be the this value.
  2. Return ? CreateHTML(S, "sup", "", "").

B.2.2.15 String.prototype.trimLeft ( )

Note

The property "trimStart" is preferred. The "trimLeft" property is provided principally for compatibility with old code. It is recommended that the "trimStart" property be used in new ECMAScript code.

The initial value of the "trimLeft" property is %String.prototype.trimStart%, defined in 22.1.3.34.

B.2.2.16 String.prototype.trimRight ( )

Note

The property "trimEnd" is preferred. The "trimRight" property is provided principally for compatibility with old code. It is recommended that the "trimEnd" property be used in new ECMAScript code.

The initial value of the "trimRight" property is %String.prototype.trimEnd%, defined in 22.1.3.33.

B.2.3 Additional Properties of the Date.prototype Object

B.2.3.1 Date.prototype.getYear ( )

Note

The getFullYear method is preferred for nearly all purposes, because it avoids the “year 2000 problem.”

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. If t is NaN, return NaN.
  5. Return YearFromTime(LocalTime(t)) - 1900𝔽.

B.2.3.2 Date.prototype.setYear ( year )

Note

The setFullYear method is preferred for nearly all purposes, because it avoids the “year 2000 problem.”

This method performs the following steps when called:

  1. Let dateObject be the this value.
  2. Perform ? RequireInternalSlot(dateObject, [[DateValue]]).
  3. Let t be dateObject.[[DateValue]].
  4. Let y be ? ToNumber(year).
  5. If t is NaN, set t to +0𝔽; otherwise set t to LocalTime(t).
  6. Let yyyy be MakeFullYear(y).
  7. Let d be MakeDay(yyyy, MonthFromTime(t), DateFromTime(t)).
  8. Let date be MakeDate(d, TimeWithinDay(t)).
  9. Let u be TimeClip(UTC(date)).
  10. Set dateObject.[[DateValue]] to u.
  11. Return u.

B.2.3.3 Date.prototype.toGMTString ( )

Note

The toUTCString method is preferred. This method is provided principally for compatibility with old code.

The initial value of the "toGMTString" property is %Date.prototype.toUTCString%, defined in 21.4.4.43.

B.2.4 Additional Properties of the RegExp.prototype Object

B.2.4.1 RegExp.prototype.compile ( pattern, flags )

This method performs the following steps when called:

  1. Let O be the this value.
  2. Perform ? RequireInternalSlot(O, [[RegExpMatcher]]).
  3. If pattern is an Object and pattern has a [[RegExpMatcher]] internal slot, then
    1. If flags is not undefined, throw a TypeError exception.
    2. Let P be pattern.[[OriginalSource]].
    3. Let F be pattern.[[OriginalFlags]].
  4. Else,
    1. Let P be pattern.
    2. Let F be flags.
  5. Return ? RegExpInitialize(O, P, F).
Note

This method completely reinitializes the this value RegExp with a new pattern and flags. An implementation may interpret use of this method as an assertion that the resulting RegExp object will be used multiple times and hence is a candidate for extra optimization.

B.3 Other Additional Features

B.3.1 Labelled Function Declarations

Prior to ECMAScript 2015, the specification of LabelledStatement did not allow for the association of a statement label with a FunctionDeclaration. However, a labelled FunctionDeclaration was an allowable extension for non-strict code and most browser-hosted ECMAScript implementations supported that extension. In ECMAScript 2015 and later, the grammar production for LabelledStatement permits use of FunctionDeclaration as a LabelledItem but 14.13.1 includes an Early Error rule that produces a Syntax Error if that occurs. That rule is modified with the addition of the highlighted text:

LabelledItem : FunctionDeclaration
  • It is a Syntax Error if any source text that is strict mode code is matched by this production.
Note

The early error rules for WithStatement, IfStatement, and IterationStatement prevent these statements from containing a labelled FunctionDeclaration in non-strict code.

B.3.2 Block-Level Function Declarations Web Legacy Compatibility Semantics

Prior to ECMAScript 2015, the ECMAScript specification did not define the occurrence of a FunctionDeclaration as an element of a Block statement's StatementList. However, support for that form of FunctionDeclaration was an allowable extension and most browser-hosted ECMAScript implementations permitted them. Unfortunately, the semantics of such declarations differ among those implementations. Because of these semantic differences, existing web ECMAScript source text that uses Block level function declarations is only portable among browser implementations if the usage only depends upon the semantic intersection of all of the browser implementations for such declarations. The following are the use cases that fall within that intersection semantics:

  1. A function is declared and only referenced within a single block.

    • One or more FunctionDeclarations whose BindingIdentifier is the name f occur within the function code of an enclosing function g and that declaration is nested within a Block.
    • No other declaration of f that is not a var declaration occurs within the function code of g.
    • All occurrences of f as an IdentifierReference are within the StatementList of the Block containing the declaration of f.
  2. A function is declared and possibly used within a single Block but also referenced by an inner function definition that is not contained within that same Block.

    • One or more FunctionDeclarations whose BindingIdentifier is the name f occur within the function code of an enclosing function g and that declaration is nested within a Block.
    • No other declaration of f that is not a var declaration occurs within the function code of g.
    • There may be occurrences of f as an IdentifierReference within the StatementList of the Block containing the declaration of f.
    • There is at least one occurrence of f as an IdentifierReference within another function h that is nested within g and no other declaration of f shadows the references to f from within h.
    • All invocations of h occur after the declaration of f has been evaluated.
  3. A function is declared and possibly used within a single block but also referenced within subsequent blocks.

    • One or more FunctionDeclaration whose BindingIdentifier is the name f occur within the function code of an enclosing function g and that declaration is nested within a Block.
    • No other declaration of f that is not a var declaration occurs within the function code of g.
    • There may be occurrences of f as an IdentifierReference within the StatementList of the Block containing the declaration of f.
    • There is at least one occurrence of f as an IdentifierReference within the function code of g that lexically follows the Block containing the declaration of f.

The first use case is interoperable with the semantics of Block level function declarations provided by ECMAScript 2015. Any pre-existing ECMAScript source text that employs that use case will operate using the Block level function declarations semantics defined by clauses 10, 14, and 15.

ECMAScript 2015 interoperability for the second and third use cases requires the following extensions to the clause 10, clause 15, clause 19.2.1 and clause 16.1.7 semantics.

If an ECMAScript implementation has a mechanism for reporting diagnostic warning messages, a warning should be produced when code contains a FunctionDeclaration for which these compatibility semantics are applied and introduce observable differences from non-compatibility semantics. For example, if a var binding is not introduced because its introduction would create an early error, a warning message should not be produced.

B.3.2.1 Changes to FunctionDeclarationInstantiation

During FunctionDeclarationInstantiation the following steps are performed in place of step 31:

  1. If strict is false, then
    1. For each FunctionDeclaration f that is directly contained in the StatementList of any Block, CaseClause, or DefaultClause x such that code Contains x is true, do
      1. Let F be the StringValue of the BindingIdentifier of f.
      2. If replacing the FunctionDeclaration f with a VariableStatement that has F as a BindingIdentifier would not produce any Early Errors for func and parameterNames does not contain F, then
        1. NOTE: A var binding for F is only instantiated here if it is neither a VarDeclaredName, the name of a formal parameter, or another FunctionDeclaration.
        2. If instantiatedVarNames does not contain F and F is not "arguments", then
          1. Perform ! varEnv.CreateMutableBinding(F, false).
          2. Perform ! varEnv.InitializeBinding(F, undefined).
          3. Append F to instantiatedVarNames.
        3. When the FunctionDeclaration f is evaluated, perform the following steps in place of the FunctionDeclaration Evaluation algorithm provided in 15.2.6:
          1. Let fEnv be the running execution context's VariableEnvironment.
          2. Let bEnv be the running execution context's LexicalEnvironment.
          3. Let fObj be ! bEnv.GetBindingValue(F, false).
          4. Perform ! fEnv.SetMutableBinding(F, fObj, false).
          5. Return unused.

B.3.2.2 Changes to GlobalDeclarationInstantiation

During GlobalDeclarationInstantiation the following steps are performed in place of step 12:

  1. Perform the following steps:
    1. Let strict be ScriptIsStrict of script.
    2. If strict is false, then
      1. Let declaredFunctionOrVarNames be the list-concatenation of declaredFunctionNames and declaredVarNames.
      2. For each FunctionDeclaration f that is directly contained in the StatementList of any Block, CaseClause, or DefaultClause x such that script Contains x is true, do
        1. Let F be the StringValue of the BindingIdentifier of f.
        2. If replacing the FunctionDeclaration f with a VariableStatement that has F as a BindingIdentifier would not produce any Early Errors for script, then
          1. If HasLexicalDeclaration(env, F) is false, then
            1. Let fnDefinable be ? CanDeclareGlobalVar(env, F).
            2. If fnDefinable is true, then
              1. NOTE: A var binding for F is only instantiated here if it is neither a VarDeclaredName nor the name of another FunctionDeclaration.
              2. If declaredFunctionOrVarNames does not contain F, then
                1. Perform ? CreateGlobalVarBinding(env, F, false).
                2. Append F to declaredFunctionOrVarNames.
              3. When the FunctionDeclaration f is evaluated, perform the following steps in place of the FunctionDeclaration Evaluation algorithm provided in 15.2.6:
                1. Let gEnv be the running execution context's VariableEnvironment.
                2. Let bEnv be the running execution context's LexicalEnvironment.
                3. Let fObj be ! bEnv.GetBindingValue(F, false).
                4. Perform ? gEnv.SetMutableBinding(F, fObj, false).
                5. Return unused.

B.3.2.3 Changes to EvalDeclarationInstantiation

During EvalDeclarationInstantiation the following steps are performed in place of step 13:

  1. If strict is false, then
    1. Let declaredFunctionOrVarNames be the list-concatenation of declaredFunctionNames and declaredVarNames.
    2. For each FunctionDeclaration f that is directly contained in the StatementList of any Block, CaseClause, or DefaultClause x such that body Contains x is true, do
      1. Let F be the StringValue of the BindingIdentifier of f.
      2. If replacing the FunctionDeclaration f with a VariableStatement that has F as a BindingIdentifier would not produce any Early Errors for body, then
        1. Let bindingExists be false.
        2. Let thisEnv be lexEnv.
        3. Assert: The following loop will terminate.
        4. Repeat, while thisEnv is not varEnv,
          1. If thisEnv is not an Object Environment Record, then
            1. If ! thisEnv.HasBinding(F) is true, then
              1. Let bindingExists be true.
          2. Set thisEnv to thisEnv.[[OuterEnv]].
        5. If bindingExists is false and varEnv is a Global Environment Record, then
          1. If HasLexicalDeclaration(varEnv, F) is false, then
            1. Let fnDefinable be ? CanDeclareGlobalVar(varEnv, F).
          2. Else,
            1. Let fnDefinable be false.
        6. Else,
          1. Let fnDefinable be true.
        7. If bindingExists is false and fnDefinable is true, then
          1. If declaredFunctionOrVarNames does not contain F, then
            1. If varEnv is a Global Environment Record, then
              1. Perform ? CreateGlobalVarBinding(varEnv, F, true).
            2. Else,
              1. Let bindingExists be ! varEnv.HasBinding(F).
              2. If bindingExists is false, then
                1. Perform ! varEnv.CreateMutableBinding(F, true).
                2. Perform ! varEnv.InitializeBinding(F, undefined).
            3. Append F to declaredFunctionOrVarNames.
          2. When the FunctionDeclaration f is evaluated, perform the following steps in place of the FunctionDeclaration Evaluation algorithm provided in 15.2.6:
            1. Let gEnv be the running execution context's VariableEnvironment.
            2. Let bEnv be the running execution context's LexicalEnvironment.
            3. Let fObj be ! bEnv.GetBindingValue(F, false).
            4. Perform ? gEnv.SetMutableBinding(F, fObj, false).
            5. Return unused.

B.3.2.4 Changes to Block Static Semantics: Early Errors

The rules for the following production in 14.2.1 are modified with the addition of the highlighted text:

Block : { StatementList }

B.3.2.5 Changes to switch Statement Static Semantics: Early Errors

The rules for the following production in 14.12.1 are modified with the addition of the highlighted text:

SwitchStatement : switch ( Expression ) CaseBlock

B.3.2.6 Changes to BlockDeclarationInstantiation

During BlockDeclarationInstantiation the following steps are performed in place of step 3.a.ii.1:

  1. If ! env.HasBinding(dn) is false, then
    1. Perform ! env.CreateMutableBinding(dn, false).

During BlockDeclarationInstantiation the following steps are performed in place of step 3.b.iii:

  1. Perform the following steps:
    1. If the binding for fn in env is an uninitialized binding, then
      1. Perform ! env.InitializeBinding(fn, fo).
    2. Else,
      1. Assert: d is a FunctionDeclaration.
      2. Perform ! env.SetMutableBinding(fn, fo, false).

B.3.3 FunctionDeclarations in IfStatement Statement Clauses

The following augments the IfStatement production in 14.6:

IfStatement[Yield, Await, Return] : if ( Expression[+In, ?Yield, ?Await] ) FunctionDeclaration[?Yield, ?Await, ~Default] else Statement[?Yield, ?Await, ?Return] if ( Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return] else FunctionDeclaration[?Yield, ?Await, ~Default] if ( Expression[+In, ?Yield, ?Await] ) FunctionDeclaration[?Yield, ?Await, ~Default] else FunctionDeclaration[?Yield, ?Await, ~Default] if ( Expression[+In, ?Yield, ?Await] ) FunctionDeclaration[?Yield, ?Await, ~Default] [lookahead ≠ else]

This production only applies when parsing non-strict code. Source text matched by this production is processed as if each matching occurrence of FunctionDeclaration[?Yield, ?Await, ~Default] was the sole StatementListItem of a BlockStatement occupying that position in the source text. The semantics of such a synthetic BlockStatement includes the web legacy compatibility semantics specified in B.3.2.

B.3.4 VariableStatements in Catch Blocks

The content of subclause 14.15.1 is replaced with the following:

Catch : catch ( CatchParameter ) Block Note

The Block of a Catch clause may contain var declarations that bind a name that is also bound by the CatchParameter. At runtime, such bindings are instantiated in the VariableDeclarationEnvironment. They do not shadow the same-named bindings introduced by the CatchParameter and hence the Initializer for such var declarations will assign to the corresponding catch parameter rather than the var binding.

This modified behaviour also applies to var and function declarations introduced by direct eval calls contained within the Block of a Catch clause. This change is accomplished by modifying the algorithm of 19.2.1.3 as follows:

Step 3.d.i.2.a.i is replaced by:

  1. If thisEnv is not the Environment Record for a Catch clause, throw a SyntaxError exception.

Step 13.b.ii.4.a.i.i is replaced by:

  1. If thisEnv is not the Environment Record for a Catch clause, let bindingExists be true.

B.3.5 Initializers in ForIn Statement Heads

The following augments the ForInOfStatement production in 14.7.5:

ForInOfStatement[Yield, Await, Return] : for ( var BindingIdentifier[?Yield, ?Await] Initializer[~In, ?Yield, ?Await] in Expression[+In, ?Yield, ?Await] ) Statement[?Yield, ?Await, ?Return]

This production only applies when parsing non-strict code.

The static semantics of ContainsDuplicateLabels in 8.3.1 are augmented with the following:

ForInOfStatement : for ( var BindingIdentifier Initializer in Expression ) Statement
  1. Return ContainsDuplicateLabels of Statement with argument labelSet.

The static semantics of ContainsUndefinedBreakTarget in 8.3.2 are augmented with the following:

ForInOfStatement : for ( var BindingIdentifier Initializer in Expression ) Statement
  1. Return ContainsUndefinedBreakTarget of Statement with argument labelSet.

The static semantics of ContainsUndefinedContinueTarget in 8.3.3 are augmented with the following:

ForInOfStatement : for ( var BindingIdentifier Initializer in Expression ) Statement
  1. Return ContainsUndefinedContinueTarget of Statement with arguments iterationSet and « ».

The static semantics of IsDestructuring in 14.7.5.2 are augmented with the following:

BindingIdentifier : Identifier yield await
  1. Return false.

The static semantics of VarDeclaredNames in 8.2.6 are augmented with the following:

ForInOfStatement : for ( var BindingIdentifier Initializer in Expression ) Statement
  1. Let names1 be the BoundNames of BindingIdentifier.
  2. Let names2 be the VarDeclaredNames of Statement.
  3. Return the list-concatenation of names1 and names2.

The static semantics of VarScopedDeclarations in 8.2.7 are augmented with the following:

ForInOfStatement : for ( var BindingIdentifier Initializer in Expression ) Statement
  1. Let declarations1 be « BindingIdentifier ».
  2. Let declarations2 be the VarScopedDeclarations of Statement.
  3. Return the list-concatenation of declarations1 and declarations2.

The runtime semantics of ForInOfLoopEvaluation in 14.7.5.5 are augmented with the following:

ForInOfStatement : for ( var BindingIdentifier Initializer in Expression ) Statement
  1. Let bindingId be the StringValue of BindingIdentifier.
  2. Let lhs be ? ResolveBinding(bindingId).
  3. If IsAnonymousFunctionDefinition(Initializer) is true, then
    1. Let value be ? NamedEvaluation of Initializer with argument bindingId.
  4. Else,
    1. Let rhs be ? Evaluation of Initializer.
    2. Let value be ? GetValue(rhs).
  5. Perform ? PutValue(lhs, value).
  6. Let keyResult be ? ForIn/OfHeadEvaluation(« », Expression, enumerate).
  7. Return ? ForIn/OfBodyEvaluation(BindingIdentifier, Statement, keyResult, enumerate, var-binding, labelSet).

B.3.6 The [[IsHTMLDDA]] Internal Slot

An [[IsHTMLDDA]] internal slot may exist on host-defined objects. Objects with an [[IsHTMLDDA]] internal slot behave like undefined in the ToBoolean and IsLooselyEqual abstract operations and when used as an operand for the typeof operator.

Note

Objects with an [[IsHTMLDDA]] internal slot are never created by this specification. However, the document.all object in web browsers is a host-defined exotic object with this slot that exists for web compatibility purposes. There are no other known examples of this type of object and implementations should not create any with the exception of document.all.

B.3.6.1 Changes to ToBoolean

The following step replaces step 3 of ToBoolean:

  1. If argument is an Object and argument has an [[IsHTMLDDA]] internal slot, return false.

B.3.6.2 Changes to IsLooselyEqual

The following steps replace step 4 of IsLooselyEqual:

  1. Perform the following steps:
    1. If x is an Object, x has an [[IsHTMLDDA]] internal slot, and y is either undefined or null, return true.
    2. If x is either undefined or null, y is an Object, and y has an [[IsHTMLDDA]] internal slot, return true.

B.3.6.3 Changes to the typeof Operator

The following step replaces step 12 of the evaluation semantics for typeof:

  1. If val has an [[IsHTMLDDA]] internal slot, return "undefined".

B.3.7 Non-default behaviour in HostMakeJobCallback

The HostMakeJobCallback abstract operation allows hosts which are web browsers to specify non-default behaviour.

B.3.8 Non-default behaviour in HostEnsureCanAddPrivateElement

The HostEnsureCanAddPrivateElement abstract operation allows hosts which are web browsers to specify non-default behaviour.

B.3.9 Runtime Errors for Function Call Assignment Targets

When a function call (13.3.6) is used as an assignment target in non-strict code, instead of producing an early error, a ReferenceError exception is thrown during evaluation of the assignment.

Note

When the assignment target is the LeftHandSideExpression of an AssignmentExpression, the assignment operator must be = or an AssignmentOperator; in particular, the allowance here does not apply to the logical assignment operators (??=, &&=, ||=).

See step 1 of AssignmentTargetType for CallExpression : CoverCallExpressionAndAsyncArrowHead and CallExpression : CallExpression Arguments .

Annex C (informative) The Strict Mode of ECMAScript

The strict mode restriction and exceptions

Annex D (informative) Host Layering Points

See 4.2 for the definition of host.

D.1 Host Hooks

HostCallJobCallback(...)

HostEnqueueFinalizationRegistryCleanupJob(...)

HostEnqueueGenericJob(...)

HostEnqueuePromiseJob(...)

HostEnqueueTimeoutJob(...)

HostEnsureCanCompileStrings(...)

HostFinalizeImportMeta(...)

HostGetImportMetaProperties(...)

HostGrowSharedArrayBuffer(...)

HostHasSourceTextAvailable(...)

HostLoadImportedModule(...)

HostGetSupportedImportAttributes(...)

HostMakeJobCallback(...)

HostPromiseRejectionTracker(...)

HostResizeArrayBuffer(...)

InitializeHostDefinedRealm(...)

D.2 Host-defined Fields

[[HostDefined]] on Realm Records: See Table 24.

[[HostDefined]] on Script Records: See Table 39.

[[HostDefined]] on Module Records: See Table 43.

[[HostDefined]] on JobCallback Records: See Table 28.

[[HostSynchronizesWith]] on Candidate Executions: See Table 101.

[[IsHTMLDDA]]: See B.3.6.

D.3 Host-defined Objects

The global object: See clause 19.

D.4 Running Jobs

Preparation steps before, and cleanup steps after, invocation of Job Abstract Closures. See 9.5.

D.5 Internal Methods of Exotic Objects

Any of the essential internal methods in Table 4 for any exotic object not specified within this specification.

D.6 Built-in Objects and Methods

Any built-in objects and methods not defined within this specification, except as restricted in 17.1.

Annex E (informative) Corrections and Clarifications in ECMAScript 2015 with Possible Compatibility Impact

9.1.1.4.14-9.1.1.4.17 Edition 5 and 5.1 used a property existence test to determine whether a global object property corresponding to a new global declaration already existed. ECMAScript 2015 uses an own property existence test. This corresponds to what has been most commonly implemented by web browsers.

10.4.2.1: The 5th Edition moved the capture of the current array length prior to the integer conversion of the array index or new length value. However, the captured length value could become invalid if the conversion process has the side-effect of changing the array length. ECMAScript 2015 specifies that the current array length must be captured after the possible occurrence of such side-effects.

21.4.1.31: Previous editions permitted the TimeClip abstract operation to return either +0𝔽 or -0𝔽 as the representation of a 0 time value. ECMAScript 2015 specifies that +0𝔽 always returned. This means that for ECMAScript 2015 the time value of a Date is never observably -0𝔽 and methods that return time values never return -0𝔽.

21.4.1.32: If a UTC offset representation is not present, the local time zone is used. Edition 5.1 incorrectly stated that a missing time zone should be interpreted as "z".

21.4.4.36: If the year cannot be represented using the Date Time String Format specified in 21.4.1.32 a RangeError exception is thrown. Previous editions did not specify the behaviour for that case.

21.4.4.41: Previous editions did not specify the value returned by Date.prototype.toString when the time value is NaN. ECMAScript 2015 specifies the result to be the String value "Invalid Date".

22.2.4.1, 22.2.6.13.1: Any LineTerminator code points in the value of the "source" property of a RegExp instance must be expressed using an escape sequence. Edition 5.1 only required the escaping of /.

22.2.6.8, 22.2.6.11: In previous editions, the specifications for String.prototype.match and String.prototype.replace was incorrect for cases where the pattern argument was a RegExp value whose global flag is set. The previous specifications stated that for each attempt to match the pattern, if lastIndex did not change, it should be incremented by 1. The correct behaviour is that lastIndex should be incremented by 1 only if the pattern matched the empty String.

23.1.3.30: Previous editions did not specify how a NaN value returned by a comparator was interpreted by Array.prototype.sort. ECMAScript 2015 specifies that such as value is treated as if +0𝔽 was returned from the comparator. ECMAScript 2015 also specifies that ToNumber is applied to the result returned by a comparator. In previous editions, the effect of a comparator result that is not a Number value was implementation-defined. In practice, implementations call ToNumber.

Annex F (informative) Additions and Changes That Introduce Incompatibilities with Prior Editions

6.2.5: In ECMAScript 2015, Function calls are not allowed to return a Reference Record.

7.1.4.1: In ECMAScript 2015, ToNumber applied to a String value now recognizes and converts BinaryIntegerLiteral and OctalIntegerLiteral numeric strings. In previous editions such strings were converted to NaN.

9.3: In ECMAScript 2018, Template objects are canonicalized based on Parse Node (source location), instead of across all occurrences of that template literal or tagged template in a Realm in previous editions.

12.2: In ECMAScript 2016, Unicode 8.0.0 or higher is mandated, as opposed to ECMAScript 2015 which mandated Unicode 5.1. In particular, this caused U+180E MONGOLIAN VOWEL SEPARATOR, which was in the Space_Separator (Zs) category and thus treated as whitespace in ECMAScript 2015, to be moved to the Format (Cf) category (as of Unicode 6.3.0). This causes whitespace-sensitive methods to behave differently. For example, "\u180E".trim().length was 0 in previous editions, but 1 in ECMAScript 2016 and later. Additionally, ECMAScript 2017 mandated always using the latest version of the Unicode Standard.

12.7: In ECMAScript 2015, the valid code points for an IdentifierName are specified in terms of the Unicode properties “ID_Start” and “ID_Continue”. In previous editions, the valid IdentifierName or Identifier code points were specified by enumerating various Unicode code point categories.

12.10.1: In ECMAScript 2015, Automatic Semicolon Insertion adds a semicolon at the end of a do-while statement if the semicolon is missing. This change aligns the specification with the actual behaviour of most existing implementations.

13.2.5.1: In ECMAScript 2015, it is no longer an early error to have duplicate property names in Object Initializers.

13.15.1: In ECMAScript 2015, strict mode code containing an assignment to an immutable binding such as the function name of a FunctionExpression does not produce an early error. Instead it produces a runtime error.

14.2: In ECMAScript 2015, a StatementList beginning with the token let followed by the input elements LineTerminator then Identifier is the start of a LexicalDeclaration. In previous editions, automatic semicolon insertion would always insert a semicolon before the Identifier input element.

14.5: In ECMAScript 2015, a StatementListItem beginning with the token let followed by the token [ is the start of a LexicalDeclaration. In previous editions such a sequence would be the start of an ExpressionStatement.

14.6.2: In ECMAScript 2015, the normal result of an IfStatement is never the value empty. If no Statement part is evaluated or if the evaluated Statement part produces a normal completion containing empty, the result of the IfStatement is undefined.

14.7: In ECMAScript 2015, if the ( token of a for statement is immediately followed by the token sequence let [ then the let is treated as the start of a LexicalDeclaration. In previous editions such a token sequence would be the start of an Expression.

14.7: In ECMAScript 2015, if the ( token of a for-in statement is immediately followed by the token sequence let [ then the let is treated as the start of a ForDeclaration. In previous editions such a token sequence would be the start of an LeftHandSideExpression.

14.7: Prior to ECMAScript 2015, an initialization expression could appear as part of the VariableDeclaration that precedes the in keyword. In ECMAScript 2015, the ForBinding in that same position does not allow the occurrence of such an initializer. In ECMAScript 2017, such an initializer is permitted only in non-strict code.

14.7: In ECMAScript 2015, the result of evaluating an IterationStatement is never a normal completion whose [[Value]] is empty. If the Statement part of an IterationStatement is not evaluated or if the final evaluation of the Statement part produces a normal completion whose [[Value]] is empty, the result of evaluating the IterationStatement is a normal completion whose [[Value]] is undefined.

14.11.2: In ECMAScript 2015, the result of evaluating a WithStatement is never a normal completion whose [[Value]] is empty. If evaluation of the Statement part of a WithStatement produces a normal completion whose [[Value]] is empty, the result of evaluating the WithStatement is a normal completion whose [[Value]] is undefined.

14.12.4: In ECMAScript 2015, the result of evaluating a SwitchStatement is never a normal completion whose [[Value]] is empty. If evaluation of the CaseBlock part of a SwitchStatement produces a normal completion whose [[Value]] is empty, the result of evaluating the SwitchStatement is a normal completion whose [[Value]] is undefined.

14.15: In ECMAScript 2015, it is an early error for a Catch clause to contain a var declaration for the same Identifier that appears as the Catch clause parameter. In previous editions, such a variable declaration would be instantiated in the enclosing variable environment but the declaration's Initializer value would be assigned to the Catch parameter.

14.15, 19.2.1.3: In ECMAScript 2015, a runtime SyntaxError is thrown if a Catch clause evaluates a non-strict direct eval whose eval code includes a var or FunctionDeclaration declaration that binds the same Identifier that appears as the Catch clause parameter.

14.15.3: In ECMAScript 2015, the result of a TryStatement is never the value empty. If the Block part of a TryStatement evaluates to a normal completion containing empty, the result of the TryStatement is undefined. If the Block part of a TryStatement evaluates to a throw completion and it has a Catch part that evaluates to a normal completion containing empty, the result of the TryStatement is undefined if there is no Finally clause or if its Finally clause evaluates to an empty normal completion.

15.4.5 In ECMAScript 2015, the function objects that are created as the values of the [[Get]] or [[Set]] attribute of accessor properties in an ObjectLiteral are not constructor functions and they do not have a "prototype" own property. In the previous edition, they were constructors and had a "prototype" property.

20.1.2.6: In ECMAScript 2015, if the argument to Object.freeze is not an object it is treated as if it was a non-extensible ordinary object with no own properties. In the previous edition, a non-object argument always causes a TypeError to be thrown.

20.1.2.8: In ECMAScript 2015, if the argument to Object.getOwnPropertyDescriptor is not an object an attempt is made to coerce the argument using ToObject. If the coercion is successful the result is used in place of the original argument value. In the previous edition, a non-object argument always causes a TypeError to be thrown.

20.1.2.10: In ECMAScript 2015, if the argument to Object.getOwnPropertyNames is not an object an attempt is made to coerce the argument using ToObject. If the coercion is successful the result is used in place of the original argument value. In the previous edition, a non-object argument always causes a TypeError to be thrown.

20.1.2.12: In ECMAScript 2015, if the argument to Object.getPrototypeOf is not an object an attempt is made to coerce the argument using ToObject. If the coercion is successful the result is used in place of the original argument value. In the previous edition, a non-object argument always causes a TypeError to be thrown.

20.1.2.16: In ECMAScript 2015, if the argument to Object.isExtensible is not an object it is treated as if it was a non-extensible ordinary object with no own properties. In the previous edition, a non-object argument always causes a TypeError to be thrown.

20.1.2.17: In ECMAScript 2015, if the argument to Object.isFrozen is not an object it is treated as if it was a non-extensible ordinary object with no own properties. In the previous edition, a non-object argument always causes a TypeError to be thrown.

20.1.2.18: In ECMAScript 2015, if the argument to Object.isSealed is not an object it is treated as if it was a non-extensible ordinary object with no own properties. In the previous edition, a non-object argument always causes a TypeError to be thrown.

20.1.2.19: In ECMAScript 2015, if the argument to Object.keys is not an object an attempt is made to coerce the argument using ToObject. If the coercion is successful the result is used in place of the original argument value. In the previous edition, a non-object argument always causes a TypeError to be thrown.

20.1.2.20: In ECMAScript 2015, if the argument to Object.preventExtensions is not an object it is treated as if it was a non-extensible ordinary object with no own properties. In the previous edition, a non-object argument always causes a TypeError to be thrown.

20.1.2.22: In ECMAScript 2015, if the argument to Object.seal is not an object it is treated as if it was a non-extensible ordinary object with no own properties. In the previous edition, a non-object argument always causes a TypeError to be thrown.

20.2.3.2: In ECMAScript 2015, the [[Prototype]] internal slot of a bound function is set to the [[GetPrototypeOf]] value of its target function. In the previous edition, [[Prototype]] was always set to %Function.prototype%.

20.2.4.1: In ECMAScript 2015, the "length" property of function instances is configurable. In previous editions it was non-configurable.

20.5.6.2: In ECMAScript 2015, the [[Prototype]] internal slot of a NativeError constructor is the Error constructor. In previous editions it was the Function prototype object.

21.4.4 In ECMAScript 2015, the Date prototype object is not a Date instance. In previous editions it was a Date instance whose TimeValue was NaN.

22.1.3.12 In ECMAScript 2015, the String.prototype.localeCompare function must treat Strings that are canonically equivalent according to the Unicode Standard as being identical. In previous editions implementations were permitted to ignore canonical equivalence and could instead use a bit-wise comparison.

22.1.3.28 and 22.1.3.30 In ECMAScript 2015, lowercase/upper conversion processing operates on code points. In previous editions such the conversion processing was only applied to individual code units. The only affected code points are those in the Deseret block of Unicode.

22.1.3.32 In ECMAScript 2015, the String.prototype.trim method is defined to recognize white space code points that may exist outside of the Unicode BMP. However, as of Unicode 7 no such code points are defined. In previous editions such code points would not have been recognized as white space.

22.2.4.1 In ECMAScript 2015, If the pattern argument is a RegExp instance and the flags argument is not undefined, a new RegExp instance is created just like pattern except that pattern's flags are replaced by the argument flags. In previous editions a TypeError exception was thrown when pattern was a RegExp instance and flags was not undefined.

22.2.6 In ECMAScript 2015, the RegExp prototype object is not a RegExp instance. In previous editions it was a RegExp instance whose pattern is the empty String.

22.2.6 In ECMAScript 2015, "source", "global", "ignoreCase", and "multiline" are accessor properties defined on the RegExp prototype object. In previous editions they were data properties defined on RegExp instances.

25.4.15: In ECMAScript 2019, Atomics.wake has been renamed to Atomics.notify to prevent confusion with Atomics.wait.

27.1.6.4, 27.6.3.6: In ECMAScript 2019, the number of Jobs enqueued by await was reduced, which could create an observable difference in resolution order between a then() call and an await expression.

Bibliography

  1. IEEE 754-2019: IEEE Standard for Floating-Point Arithmetic. Institute of Electrical and Electronic Engineers, New York (2019) Note

    There are no normative changes between IEEE 754-2008 and IEEE 754-2019 that affect the ECMA-262 specification.

  2. The Unicode Standard, available at <https://unicode.org/versions/latest>
  3. Unicode Technical Note #5: Canonical Equivalence in Applications, available at <https://unicode.org/notes/tn5/>
  4. Unicode Technical Standard #10: Unicode Collation Algorithm, available at <https://unicode.org/reports/tr10/>
  5. Unicode Standard Annex #15, Unicode Normalization Forms, available at <https://unicode.org/reports/tr15/>
  6. Unicode Standard Annex #18: Unicode Regular Expressions, available at <https://unicode.org/reports/tr18/>
  7. Unicode Standard Annex #24: Unicode Script Property, available at <https://unicode.org/reports/tr24/>
  8. Unicode Standard Annex #31, Unicode Identifiers and Pattern Syntax, available at <https://unicode.org/reports/tr31/>
  9. Unicode Standard Annex #44: Unicode Character Database, available at <https://unicode.org/reports/tr44/>
  10. Unicode Technical Standard #51: Unicode Emoji, available at <https://unicode.org/reports/tr51/>
  11. IANA Time Zone Database, available at <https://www.iana.org/time-zones>
  12. ISO 8601:2004(E) Data elements and interchange formats — Information interchange — Representation of dates and times
  13. RFC 1738 “Uniform Resource Locators (URL)”, available at <https://tools.ietf.org/html/rfc1738>
  14. RFC 2396 “Uniform Resource Identifiers (URI): Generic Syntax”, available at <https://tools.ietf.org/html/rfc2396>
  15. RFC 3629 “UTF-8, a transformation format of ISO 10646”, available at <https://tools.ietf.org/html/rfc3629>
  16. RFC 7231 “Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content”, available at <https://tools.ietf.org/html/rfc7231>

Colophon

This specification is authored on GitHub in a plaintext source format called Ecmarkup. Ecmarkup is an HTML and Markdown dialect that provides a framework and toolset for authoring ECMAScript specifications in plaintext and processing the specification into a full-featured HTML rendering that follows the editorial conventions for this document. Ecmarkup builds on and integrates a number of other formats and technologies including Grammarkdown for defining syntax and Ecmarkdown for authoring algorithm steps. PDF renderings of this specification are produced using a print stylesheet which takes advantage of the CSS Paged Media specification and is converted using PrinceXML.

Prior editions of this specification were authored using Word—the Ecmarkup source text that formed the basis of this edition was produced by converting the ECMAScript 2015 Word document to Ecmarkup using an automated conversion tool.

Copyright & Software License

Ecma International

Rue du Rhone 114

CH-1204 Geneva

Tel: +41 22 849 6000

Fax: +41 22 849 6001

Web: https://ecma-international.org/

Software License

All Software contained in this document ("Software") is protected by copyright and is being made available under the "BSD License", included below. This Software may be subject to third party rights (rights from parties other than Ecma International), including patent rights, and no licenses under such third party rights are granted under this license even if the third party concerned is a member of Ecma International. SEE THE ECMA CODE OF CONDUCT IN PATENT MATTERS AVAILABLE AT https://ecma-international.org/memento/codeofconduct.htm FOR INFORMATION REGARDING THE LICENSING OF PATENT CLAIMS THAT ARE REQUIRED TO IMPLEMENT ECMA INTERNATIONAL STANDARDS.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  3. Neither the name of the authors nor Ecma International may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE ECMA INTERNATIONAL "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ECMA INTERNATIONAL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.